259479eb1cb8b5ac83fb1047e9ccf8c5
Android 后台保活手段总结 (上篇)

Android 后台保活手段总结 (上篇)

由于众所周知的限制,在国内无法使用GCM推送服务,想要自己搭建推送服务的话,有两个绕不开的技术点,一个是TCP长连的保活,另一个就是后台进程的保活。虽然看起来是老生常谈的问题,但竟然是收到私信里问到最多的内容。于是在这里做一个目前接触的保活手段,做一个总体的总结

常规保活方案

利用Notification提升权限

Android 中 Service 的优先级为4,通过 setForeground 接口可以将后台 Service 设置为前台 Service,使进程的优先级由4提升为2,从而使进程的优先级仅仅低于用户当前正在交互的进程,与可见进程优先级一致,使进程被杀死的概率大大降低。
需要注意的是,在最新的Android 8.0系统上,setForeground变成了强制性的行为,任何后台Service都必须调用这个方法,否则五秒钟后系统强制ANR Crash。这里涉及到另外的一个坑是——哪怕你的Service只是做点业务逻辑后销毁,也需要先调用这个接口,因为不同的国产ROM重新定义了“五秒钟”(手动滑稽),你以为只需要占用1秒的业务逻辑,上线都可能分分钟崩溃给你看。
然而调用这个API后,系统通知栏上会显示“XXX应用在后台运行”,无法去掉。8.1系统上已经去掉了这个很不友好的通知栏常驻显示。

利用系统广播拉活

在发生特定系统事件时,系统会发出响应的广播,通过在 AndroidManifest 中“静态”注册对应的广播监听器,即可在发生响应事件时主动尝试拉活Service。

可以用于拉活的广播事件包括:

备注 广播事件
开机 RECEIVE_BOOT_COMPLETED
网络变化 ACCESS_NETWORK_STATE CHANGE_NETWORK_STATE ACCESS_WIFI_STATE CHANGE_WIFI_STATE ACCESS_FINE_LOCATION ACCESS_LOCATION_EXTRA_COMMANDS
文件挂载 MOUNT_UNMOUNT_FILESYSTEMS
屏幕状态变化 SCREEN_ON SCREENOFF
锁屏解锁 RECEIVER_USER_PRESENT
应用卸载安装 PACKAGE_REMOVED PACKAGE_ADDED

在Android 8.0系统上,这个方法已经不生效了,因为8.0系统已经去掉了这种静态广播注册的形式,系统广播必须使用动态注册,即应用启动后registerReceiver,在Manifest里配置广播已经无法生效。

另外,在某些深度定制的系统上效果一般,比如华为系统上,应用进程一旦终止,无法使用系统广播的形式重新唤起。

利用系统Service START_STICKY机制拉活

将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后自动拉活。最基本的方式,不解释了。

利用Native进程拉活

Native双进程守护的方式曾经风靡一时,被当做“黑科技”,然而遗憾的是实际上效果一般,仅仅在5.0以下系统兼容较好,深度定制的系统中:魅族、华为、小米等,都效果略差。从recent中杀进程后无法重新拉起,后台一段时间以后也会被杀掉。仅适合5.0以下版本仍然较高的APP采用这种方法。

top Created with Sketch.