Android中进程保活方案总结

Posted by JamesPxy on 2019-10-22

1. 概述

1.1 Android中进程被杀场景

home_posts_tag-true

1.2 进程保活策略图

pic2

2. 进程运行期间保活

Android 中对于内存的回收,主要依靠 Lowmemorykiller 来完成,是一种根据 OOM_ADJ 阈值级别触发相应力度的内存回收的机制。在 Lowmemorykiller 回收内存时会根据进程的级别优先杀死 OOM_ADJ 比较大的进程,对于优先级相同的进程则进一步受到进程所占内存和进程存活时间的影响。
下图为Android中的进程优先级以及系统回收策略:

pic3

关于进程分类详见官方文档:链接
综上,可以得出减少进程被杀死概率无非就是想办法提高进程优先级,减少进程在内存不足等情况下被杀死的概率,以下两种策略本质上是都是提升进程优先级OOM_ADJ。

2.1 一像素悬浮activity

系统一般不会杀死前台进程,所以要使进程常驻,只需要监听系统的锁屏广播:打开屏幕的时候关闭 一个像素的Activity;锁屏的时候开启一个 一个像素的Activity。
此方案只能尽可能降低APP进程被系统杀掉概率,对于用户主动清理以及内存不足情况下依然会被杀,所以不推荐。

2.2 前台服务,开启隐藏Notification的Service

利用 Notification 提升权限,开启前台服务startForeground(),其实就是利用 前台Service的漏洞
对于 API level < 18 ,调用 startForeground(ID, new Notification()),发送的是空的 Nofication,图标则不会显示;
对于 API level >= 18 ,在优先级的 KeepLiveService中启动 一个 InnerService,让两个服务同时启动 startFroeground(),且绑定同样的 Id,然后再停掉InnerService
经测试在8.0及以上这种方案无法隐藏通知栏消息,只有两个service都stop之后才能取消通知栏消息提示。所以这里涉及到权衡控制什么时候该显示“交易猫正在运行”通知栏消息。

3. 进程死后拉活

3.1 利用系统广播拉活

在发生特定系统事件时,系统会发出响应的广播,通过动态注册对应的广播监听器,即可在发生响应事件时拉活。
常用广播:开机广播、网络变化、文件挂载、屏幕亮灭、锁屏解锁、蓝牙开关、应用安装卸载
但存在问题如下:
需要引导用户去开启“自启动”权限,否则会无法接收到系统特定广播,从而无法自启。一般用户不会开启此权限,所以可以作为备用策略。
系统广播事件不可控,只能保证发生事件时拉活进程,但无法保证进程挂掉后立即拉活。

3.2 JobScheduler拉活

5.0以上基于JobScheduler进行保活,5.0以下通过ALARM_SERVICE,添加重复唤醒闹钟,不停唤醒服务
当一系列预置的条件被满足时,JobScheduler API为你的应用执行一个操作。与AlarmManager不同的是这个执行时间是不确定的。除此之外,JobScheduler API允许同时执行多个任务。这允许你的应用执行某些指定的任务时不需要考虑时机控制引起的电池消耗。
需要注意:setPeriodic:按时间间隔执行周期性作业,在Android 5、6平台版本下可以间隔任何时间运行,在Android7.0平台版本上需设置定期作业的间隔时间>=15分钟时才能运行。

3.3 借助系统NotificationListenerService API>18

NotificationListenerService是用来监听手机通知栏消息的,继承NotificationListenerService监听系统通知栏消息进而拉活服务
缺点:需要用户手动开启通知栏权限,而且存在兼容性问题,在oppo、vivo手机上有可能监听不到通知栏服务。

3.4 账号同步机制实现保活(AccountSync)

Android 系统的账号同步机制会定期同步账号进行,利用系统的同步机制进行进程的拉活。
存在问题:
SyncAdapter时间进度不高,往往会因为手机处于休眠状态,而时间往后调整,同步间隔最低为1分钟
用户可以单独停止或者删除,有些手机账号默认是不同步的,需要手动开启
经我在小米手机上测试如果不开启“自启动”权限并不能在force-stop后拉活进程

3.5 应用间相互唤醒,第三方广播拉活

该方案与接收系统广播类似,不同的是该方案为接收第三方 Top 应用广播。通过反编译第三方 Top 应用,如:手机QQ、微信、支付宝、UC浏览器等,以及友盟、信鸽等 SDK,找出它们外发的广播,在应用中进行监听,这样当这些应用发出广播时,就会将我们的应用拉活。
存在问题:第三方应用的广播属于应用私有,当前版本中有效的广播,在后续版本随时就可能被移除或被改为不外发。以及需要反编译了解多个广播保活才能有所效果。

3.6 官方push通道拉活

通过接入官方消息推送渠道达到唤醒APP目的,主要包括:小米、华为、oppo、vivo、魅族等第三方厂商推送,如果国内的Android推送联盟统一了推送渠道后续可能就不需要针对特定厂商去做接入工作了,当然目前看来遥遥无期。眼下接入商官方推送渠道比较靠谱。

3.7 利用Native进程拉活

利用 Linux 中的 fork 机制创建 Native 进程,在 Native 进程中监控主进程的存活,当主进程挂掉后,在 Native 进程中立即对主进程进行拉活。在 Android 中所有进程和系统组件的生命周期受 ActivityManagerService 的统一管理。而且,通过 Linux 的 fork 机制创建的进程为纯 Linux 进程,其生命周期不受 Android 的管理。
该方案在Android5.0 以下版本拉活效果非常好,不受 forcestop 影响,被强制停止的应用依然可以被拉活,但Android5.0 以上系统对 Native 进程等加强了管理,Native 拉活方式失效。
在 Native 进程中通过死循环或定时器,轮训判断主进程是否存活,如果进程不存活时进行拉活。该方案的很大缺点是不停的轮询执行判断逻辑,非常耗电。以及目前市场上5.0以下设备占有率相对较低,所以不推荐。



支付宝打赏 微信打赏

赞赏一下