Android 保活措施你会了吗?


Android 保活措施你会了吗?

文章插图
 
这个文章只是Android历史保活方案总结,没有什么特别的参考意义,Android 已经到10了,100%保活本身就已经不复存在,文章中所有的方案,都是有可能有用,毕竟4.4还有人用,至于要不用可以自己参考,毕竟当PM就是让你应用不死,你能不写代码吗?
保活通常分为2种方案,一种为提高进程优先级,防止被杀,另一种为进程被杀死拉活
1. 进程优先级Android系统会尽可能的保持应用进程,但是当需要建立新的进程或者运行更重要的进程,便会回收优先级低一些的进程,这个就是lowmemorykiller的工作 。而进程的优先级其实就是 /proc/pid/oom_adj
进程的优先级排序
  1. 前台进程(Foreground Process)
  2. 可见进程(Visible Process)
  3. 服务进程(Service Process)
  4. 后台进程(Background Process)
  5. 空进程(Empty Process)
前台进程
  1. 拥有 用户正在交互的 Activity(正处于 onResume中)
  2. 拥有 Service绑定到正处于 onResume的 Activity
  3. 拥有 Service 调用 startForeground 成为前台服务
  4. 拥有 Service 正在执行生命周期回调(onCreate、onStart、onDestroy)
  5. 拥有 BroadcastReceiver 正在执行 onReceive
可见进程
  1. 拥有 Activity 处于 onPause,此时可见但是不可操作
  2. 拥有 Service 绑定到正处于 onPause的 Activity
服务进程
  1. 仅通过 startService 启动的 Service
后台进程
  1. 拥有 Activity 处于 onStop
空进程
  1. 不拥有任何活动的组件进程
2. 回收策略从Zygote fork出来的进程都会被储存在 ActivityManagerService.mLruProcesses 列表中,由ActivityManagerService进行统一管理 。ActivityManagerService会根据进程状态去更新进程所对应的 oom_adj 的值,当内存达到一定的阈值会触发清理 oom_adj 高的进程 。
 
Android 保活措施你会了吗?

文章插图
 
3. 保活方案3.1 提高进程优先级3.1.1 利用Activity1像素Activy,监控手机解锁屏事件,解锁时将Activity销毁,锁屏时启动,并且要无感知,在RecentTask里移除
3.1.2 前台服务+NotificationService 通过 startForegroundService 启动,低版本时可以通过特殊方式对 Notification 进行隐藏,高版本无法规避,此方案为通过需求正向解决
3.1.3 引导用户打开电池管理,允许应用后台运行【Android 保活措施你会了吗?】目前市面上的手机,或多或少都有对进程管理有优化,可能会有允许应用后台允许的功能,但是每款手机的入口均不相同,而且相同厂商的不同版本也会不同
具体做法,找到手机的电池管理或者系统的后台管理,针对不同的手机做文字书面的提醒,提醒用户开启此功能,暴力一点可以想办法拿到此Activity的具体类名 包名等信息,进行反射调用 。
此方案一般应用不要使用,工作量巨大,而且仅仅针对提醒类应用使用,比如吃药提醒,起床闹钟,这些对保活要求非常高的应用才适合
3.2 进程死后拉活3.2.1 监听系统静态广播低版本时,静态广播可以唤醒应用进程,所以监听系统广播,例如开机,锁屏,解锁等可以做到,但是高版本不能通过静态广播监听系统广播了
3.2.2 监听三方静态广播与上个方案类似,都是运用静态广播可以拉活应用为基础,只是发送方不是系统,而且三方应用 。所以此方案可行,但是很不稳定,海外和国内用户群体不同,手机使用的APK也会不同,而且需要大量反编译三方应用,投成本也很高
3.2.3 利用系统Service机制拉活Service 的 onStartCommand 返回值,当返回值为 START_STICKY 和 START_REDELIVER_INTENT 时,服务会自动重启,但是 Service 在短时间内被杀死5次,则不再拉起
3.2.4 利用 JobSchedulerJobScheduler 为Android 5.0之后引入的,本质是系统定时任务,如果进程被杀,任务仍然会被执行,在7.0后 JobScheduler 添加了限制,最低间隔为15分钟 。但是还是有概率出现存在进程死亡后,不触发的情况 。
3.2.5 利用 AlarmManager本质上也是通过设置定时任务,如果进程被杀,任务也仍然会被执行,此时就可以拉活进程 。Doze模式会影响 AlarmManager 不被触发,此时要用setAlarmClock来设置 。同样有概率出现存在进程死亡后,不触发的情况 。
而且Android 9.0的谷歌原生手机,多了一个功能,就是显示手机下一个的闹钟时间是几点,如果用到了这种保活方式,用户也注意到了这个功能,那么闹钟上的时间会暴露有应用在明目张胆的保活


推荐阅读