V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
banixc
V2EX  ›  Android

android 花式保活正确姿势求指教

  •  
  •   banixc · 2019-03-04 11:23:36 +08:00 · 15067 次点击
    这是一个创建于 2094 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求:需要开发一个 android app, 长时间保持后台,并建立 /保持 websocket 连接,服务端不定时从 ws 向客户端推送消息,客户端收到消息后进行语音播报(soundpool)。

    目前实现:

    1. 开启一个进程整一个 service 并保持 foreground notification(通知栏可以持续看到)。
    2. 让用户设置省电优化白名单
    3. 让用户将进程锁定防止被清理(任务切换界面加小锁)

    然而存在的问题:

    1. 部分手机如此设置后等一段时间就被 kill
    2. 部分手机锁屏后没有网络,ws 不通,断线或者延迟播报(十几秒,一分钟)。
    3. 部分手机锁屏后代码执行速度会下降,表现为定时 sleep1 分钟后打 log 到后面就变成几分钟打一次了(貌似是 doze 模式), 甚至到最后一条语音播报都会断断续续。

    已知的一些应用的解决方案及优化点:

    1. 各大主流国产 OS 内置对一些应用增加白名单如微信等,无需手动设置
    2. 多进程保活后相互拉起(5.0 后失效,系统直接杀死进程组)
    3. 原生进程实现,降低内存占用,可以有效防止被杀
      • 目前新开的进程没有 UI,后台内存占用大概在 30-50M 左右
      • 原生进程能在 20M 以内。
      • 由于 soodpool 预先加载资源到内存,这部分看是否可以优化
    4. 设置 alarm/注册广播

    另外还需要实现开机自启动,自动连接,无需每次开机都要打开 app 这样的功能。

    如上所述,考虑 3,4 优化点,每个点的收益如何?或者诸位大佬有无更好的解决方案?

    PS: 不要说应用流氓,用户的需求就是要常驻进程,但是应用总是被系统各种限制导致播报不及时,国产 OS 和应用的相爱相杀-。-,没有 GMS 或者类似统一推送平台的东西,最后就是是双输的局面。

    43 条回复    2019-03-07 15:35:48 +08:00
    lfzyx
        1
    lfzyx  
       2019-03-04 11:30:00 +08:00   ❤️ 1
    用 FCM 推送不就行了
    TomVista
        2
    TomVista  
       2019-03-04 11:38:52 +08:00   ❤️ 1
    同纠结这个,我用的 ajax 轮询~,插眼看结果.
    我现在就是提示用户加入白名单,但是我的用户大部分不会这个操作(年龄段),很尴尬.

    平常内存占用 6m 左右,4g 运存手机,基本不杀,除非用户打游戏,手机自带游戏模式,或者用户开了大量大厂应用导致内存不足.
    MetalCore
        3
    MetalCore  
       2019-03-04 11:48:24 +08:00   ❤️ 1
    1.监听息屏,息屏时是尽量保持应用能置顶(不能置顶,应用很快就 gg )
    2.建议用户使用爱国牌手机,使用爱国牌推送唤醒
    3.有些手机未阉割小部件,能用小部件 30 分钟唤醒一次
    codehz
        4
    codehz  
       2019-03-04 14:19:25 +08:00   ❤️ 1
    可以考虑阻止屏幕关闭,显示一个全屏黑色悬浮窗代替关闭屏幕
    HongJay
        5
    HongJay  
       2019-03-04 14:29:06 +08:00   ❤️ 1
    当 ws 检测到连接断开后,通过厂商通道拉起 app
    torchmu
        6
    torchmu  
       2019-03-04 15:03:49 +08:00   ❤️ 1
    这个不会是支付平台的收款到账语音播报吧。
    目前支付宝都没法代码层面解决,详情可以参考支付宝设置到账提醒里的引导手册 doge
    yukiww233
        7
    yukiww233  
       2019-03-04 15:49:21 +08:00   ❤️ 1
    基本没办法,现在还有完美保活方案的话卖给国内互联网公司都可以财富自由了
    gam2046
        8
    gam2046  
       2019-03-04 15:59:22 +08:00   ❤️ 1
    把自己的应用包名改成白名单内的?(比如支付宝、微信、QQ ?)副作用就是当用户安装这些应用的时候,你的应用与被顶包的应用,后安装的将无法安装,原因是签名校验失败。
    bertsir
        9
    bertsir  
       2019-03-04 17:27:23 +08:00   ❤️ 1
    考虑一下厂商通道的推送
    shenhb
        10
    shenhb  
       2019-03-04 17:32:45 +08:00   ❤️ 1
    每个手机的厂商,集成一套推送
    GTim
        11
    GTim  
       2019-03-04 18:11:40 +08:00   ❤️ 1
    我也是 3 和 4,4 通过监听所有的通知 ( 爱用不用 ) 3. 开启一个单独的进程,很小很小
    snowspace
        12
    snowspace  
       2019-03-04 20:19:27 +08:00   ❤️ 1
    推必达
    NotificationListenerService 坚持长连接
    JobService
    等等
    不过在高版本上基本无效
    接厂商通道吧
    hanbing135
        13
    hanbing135  
       2019-03-04 20:25:15 +08:00 via Android   ❤️ 1
    可以短信推送吧
    lerp
        14
    lerp  
       2019-03-04 20:26:30 +08:00 via Android   ❤️ 1
    后台循环播放无声音频
    sampeng
        15
    sampeng  
       2019-03-04 22:51:59 +08:00 via iPhone   ❤️ 4
    虽然我是研发…但真的特别反感这个需求…始终让 cpu 无法休息。。产品是爽了。
    HongJay
        16
    HongJay  
       2019-03-05 00:12:48 +08:00   ❤️ 1
    @sampeng 开始考虑 cpu 的感受了?
    nanaw
        17
    nanaw  
       2019-03-05 01:49:18 +08:00   ❤️ 1
    可以如楼上所说,使用“特殊手段”保持手机唤醒状态,会很大的影响待机,需要用户允许,否则算是流氓了。
    别的不说,开机自启对用户来说也算很流氓的了。
    被 kill 的问题,一般是内存不足,不运行其他应用保持前台应该不会出现
    luckylo
        18
    luckylo  
       2019-03-05 08:02:42 +08:00 via Android   ❤️ 1
    给引导,让用户自己去添加白名单。别替用户做选择。
    ksssdh123
        19
    ksssdh123  
       2019-03-05 10:28:53 +08:00   ❤️ 1
    最好的方式,还是引导用户,主动去开启,一般都是在电池这设置里去开启
    banixc
        20
    banixc  
    OP
       2019-03-05 10:37:23 +08:00
    @HongJay @bertsir @shenhb @snowspace
    上面几位说到厂商通道可以试试,目前我们是非专业开发 android 的,手里没有那么多测试手机,因此接入估计也没办法测试。如果其他办法搞不定的话应该是最后的手段。
    banixc
        21
    banixc  
    OP
       2019-03-05 10:39:16 +08:00
    @codehz @torchmu
    刚看到支付宝有个增强收款模式,直接全程亮屏,正在考虑增加一个选项让屏幕永远常亮。
    banixc
        22
    banixc  
    OP
       2019-03-05 10:40:16 +08:00
    @gam2046
    这个操作有点厉害,但是我们的用户应该都有装白名单里的 app,这样搞用户会反感。
    banixc
        23
    banixc  
    OP
       2019-03-05 10:42:28 +08:00
    @nanaw @luckylo @ksssdh123
    目前采取的措施指引就是让用户加入省电白名单,但是由于不同的手机设置方法不一样,还有很多小众机型,没办法兼容到所有的手机,更何况有的手机设置了也不顶用。用户是希望常驻后台的。
    ksssdh123
        24
    ksssdh123  
       2019-03-05 10:52:14 +08:00   ❤️ 1
    @banixc
    对于这个问题 我们是这么做的(有点暴力,但我们这边的用户能接受,因为我们是某一行业领域的 app,用户群体很确定)
    产品经理 根据市场 根据用户等等因素 ,整理出一份需要适配的名单,最后让用户去选择这些机型去采购,开发只需要对这些名单上的机型做适配,每隔一段时间再对新机型做适配
    2bab
        25
    2bab  
       2019-03-05 11:45:23 +08:00   ❤️ 1
    这种用户允许下的保活,可以在 App 里给个设置,打开后起个前台的 Service,解决大部分的问题。
    2bab
        26
    2bab  
       2019-03-05 11:46:26 +08:00
    补一下,前台可以自己做 Polling 或者建个自己的 Socket Channel。
    ysc3839
        27
    ysc3839  
       2019-03-05 13:02:51 +08:00 via Android   ❤️ 1
    MIUI 挺坑的,用户开启了自启动和运行后台运行之后,一般情况下程序并不会被杀死。但是用户从最近任务里面划掉的话就会被杀死。不过程序开了自启动的话可以在后台再启动起来。
    banixc
        28
    banixc  
    OP
       2019-03-05 17:32:34 +08:00
    @ksssdh123 这个方法算是简单粗暴了,但是我们这种应该不太有可能试用这种方法。
    banixc
        29
    banixc  
    OP
       2019-03-05 17:34:45 +08:00
    @2bab 目前的做法就是起一个前台 Service,然后里面建立 websocket。但是会有网络断开 /进程被 kill/代码执行缓慢的问题。网络断开一般都是自动重连的,进程被 kill 就看怎么能恢复或者重新拉起。
    banixc
        30
    banixc  
    OP
       2019-03-05 17:36:21 +08:00
    @ysc3839 通常我们的用户不会手动干掉这个进程的,自启动不是在手机开机的时候启动吗?难道被系统杀掉之后过一段时间还会拉起来?
    boboliu
        31
    boboliu  
       2019-03-05 17:39:21 +08:00   ❤️ 1
    要不……来个悬浮窗+持续亮屏?
    ronaldong
        32
    ronaldong  
       2019-03-05 17:51:11 +08:00   ❤️ 1
    之前做即时通讯的应用的时候,研究过这个问题,基本无解
    pubby
        33
    pubby  
       2019-03-05 17:55:50 +08:00   ❤️ 1
    加点其他触发几率比较大的一些广播事件监听,再加个定时器,然后在这些监听处理里面检查这个 Service 的状态。
    息屏的问题,你 WakeLock 也处理一下

    我这边一个类似需求的 app,分布在不同的地方,长时间插电运行,websocket 和服务器连接随时接收指令做出响应。
    在 vivo,小米,华为几款手机都工作正常,基本上运行几周都不用管。

    当然开机自启权限,电源白名单之类的要手工设置好。
    0x8192dd
        34
    0x8192dd  
       2019-03-05 18:04:30 +08:00   ❤️ 1
    起一个前台 Service,保持运行,同时警告用户不要杀进程,反正明确一点,常驻后台不是没法做,但是“不经用户同意常驻后台”,在目前的高版本系统上是做不到的,也不要浪费时间去尝试了
    ysc3839
        35
    ysc3839  
       2019-03-05 18:19:51 +08:00 via Android
    @banixc 但是你不能保证用户不会不小心划掉。
    自启动开了之后是可以在程序被杀死后重新启动的,不需要用户点开就能启动。
    whitev2
        36
    whitev2  
       2019-03-05 19:07:45 +08:00   ❤️ 1
    不用花心思在保活上,我一般都是直接 小黑屋 /冰箱 冻结不需要后台的应用的。这个操作对于应用基本是无解的
    luwies
        37
    luwies  
       2019-03-05 19:54:42 +08:00   ❤️ 1
    不考虑耗电还是可以的吧,WakeLock 防止系统休眠,同时让你要保活的进程播放一个静音的音频...
    unknowngas
        38
    unknowngas  
       2019-03-06 05:53:43 +08:00   ❤️ 1
    Play soundless sound, so your app will be a music player which always play something (either voice message or soundless sound)
    ivanchou
        39
    ivanchou  
       2019-03-06 09:54:29 +08:00
    想了解下已经实现里的 2、3 是怎么做的
    banixc
        40
    banixc  
    OP
       2019-03-07 15:31:30 +08:00
    @boboliu 看了下各位大佬的回复,目前打算这样搞。
    banixc
        41
    banixc  
    OP
       2019-03-07 15:33:56 +08:00
    @0x8192dd
    @ysc3839
    @whitev2
    @ivanchou
    目前我们的用户的目的就是要让这个应用长时间在后台运行,所以做法就是告诉用户,如何设置白名单,并增加小锁(没有从代码层面实现,而是直接告诉用户)。只不过发现有些系统就算这样设置了依旧不行,实在不行就长时间亮屏呗。
    whitev2
        42
    whitev2  
       2019-03-07 15:35:38 +08:00
    @banixc #41 顺便告诉用户哪些系统不行,及时甩锅
    banixc
        43
    banixc  
    OP
       2019-03-07 15:35:48 +08:00
    @luwies
    @unknowngas
    我自己的 android 机升级到 9 之后,网易云音乐和 QQ 音乐正放着歌呢 5 分钟就直接被 kill 掉了。不过我还是试下,说不定有用呢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1023 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:49 · PVG 04:49 · LAX 12:49 · JFK 15:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.