Android 进程保活-基础理论篇

针对App持续定位,以及消息推送,通知等需要后台可唤起需求,介绍React Native App项目中落地方案。

前言

用户使用App时,集成高德地图SDK,可支持持续定位能力:

  1. iOS设置distanceFilter,即定位距离变化值为参考值进行持续性定位更新,如可设置为500米;
  2. Android以interval及间隔时间实现定时定位上报,如设为5分钟;

对于iOS 而言可以在Xcode 设置Background Location Update, 另外消息推送由APNS(Apple Push Notification Server) 统一服务支持即时到达用户设备端,所以主要适配在于Android 端。

消息推送需要关注及时性,稳定性和到达率:

  1. 用户使用中正常推送到达;
  2. 用户app进入后台正常推送到达;
  3. 用户杀掉app进程,推送正常到达;
  4. 用户重启设备推送正常到达;

难点

  1. Android进程等级:Android系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,需要清除旧进程来回收内存。 为了确定保留或终止哪些进程,系统会对进程进行分类。 需要时,系统会首先消除重要性最低的进程,然后是清除重要性稍低一级的进程,依此类推,以回收系统资源。进程等级参考 谷歌官方文档
  2. Low Memory Killer:根据 OOM_ADJ 阈值级别触发相应力度的内存回收的机制。
  3. 各大国产厂商ROOM定制优化,如手机管家,电池优化,自启动/后台运行限制;
  4. Android 6.0 Doze休眠模式及App StandyBy优化模式,限制进程/服务执行,进入吊起状态;

保活方案

  1. 监听广播拉活 :监听全局的静态广播,比如时间更新的广播、开机广播、解锁屏、网络状态、解锁加锁亮屏暗屏(3.1版本),高版本需要应用开机后运行一次才能监听这些系统广播,目前此方案失效。可以更换思路,做APP启动后的保活(监听广播启动保活的前台服务)
  2. 系统Service机制拉活 :将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后自动拉活。但是某些ROM 系统不会拉活。并且经过测试,Service 第一次被异常杀死后很快被重启,第二次会比第一次慢,第三次又会比前一次慢,一旦在短时间内 Service 被杀死4-5次,则系统不再拉起。
  3. 定时器 :创建定时器定时运行拉起App进程,但是当应用被系统杀死时,定时器也将失效,此方案失效;
  4. JobScheduler :JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利用它的这个特点完成保活的功能,效果类似开启一个定时器,与普通定时器不同的是其调度由系统完成。它是在Android5.0之后推出的,在5.0之前无法使用,在5.0,5.1,6.0作用很大,7.0时候有一定影响(可以在电源管理中给APP授权)。假如应用被系统杀死,那么定时器则失效,此方案失效。
  5. AIDL双进程、双Service守护 :Service可以以bind方式启动,当Service被系统杀死的时候,会在ServiceConnection的onServiceDisconnected方法中会收到回调。利用这个原理,可以在主进程中进行有一个LocalService,在子进程中有RemoteService。LocalService中以bind和start方式启动RemoteService,同时RemoteService以bind和start方式启动LocalService。并且在它们各自的ServiceConnection的onServiceDisconnected方法中重新bind和start。高版本此方案已失效,5.0起系统回收策略改成进程组。双Service方案也改成了应用被杀,任何后台Service无法正常状态运行;
  6. 提高Service优先级 :只能一定程度上缓解Service被立马回收,可包括常驻通知栏(可通过启动另外一个服务关闭Notification,不对oom_adj值有影响)、使用”1像素“的Activity覆盖在getWindow()的view上、循环播放无声音频(黑科技,7.0下杀不掉)
  7. 账户同步拉活 :使用Android 系统账户同步拉活;
  8. 使用自定义锁屏界面 :覆盖系统锁屏界面;
  9. 手机管家白名单 :跳转到系统白名单界面让用户添加app进入白名单;
  10. 电池优化白名单 :询问用户取消系统电池限制优化,加入白名单;
  11. 其它
  12. 推送拉活 ,根据终端不同,在小米手机接入小米推送、华为手机接入华为推送,这样也可以保证进程可以被推送唤醒;
  13. Native拉活 ,Native fork子进程用于观察当前app主进程的存亡状态。在5.0以前的系统上效果较好,5.0以上成功率极低;