Android保活机制
市面上没有100%的保活机制,除非手机厂商将该应用设置成为系统白名单(比如微信等)。我们要做的尽可能的提高APP的优先级,尽量避免其被杀死,以及被杀死后如何“复活”。
如何查看app在系统中的优先级
1 | 这里的11572要改为对应进程的id |
获取到的值参考下图:(数字越小,优先级越高)
保活法-提高优先级
目的:尽力去提升进程优先级。
1像素法
在监听到手机关闭屏幕时,偷偷创建一个只有1像素的、透明的Activity,让应用成为前台进程,然后再打开屏幕时,关掉这个Activity。
针对锁屏状态下优先级降低的情况。
前台服务保活
在启动应用的同时,创建一个前台服务(前台服务的优先级远高于普通服务),然后在该服务中又创建一个前台服务,共用同一个SERVICE_ID,然后马上销毁这个前台服务【stopSelf()
】,这样一来前台就不会出现通知栏,而前台服务(第一个service)依旧存在。如此实现了优先级的提升。
这个方法实际上是利用了Google的一个漏洞,传入同一个id创建两个前台服务可以创建成功。但是在Android 8.0以后,Google工程师修补了这个bug,所以该方法只适用于7.0及以下的手机。
拉活法-起死回生
目的:app被杀死后把他给救活。
广播拉活
在发生特定的系统事件时,系统会发出广播。此时可以通过静态注册特定的广播监听器,在收到响应事件时进行拉活。
但是自Android 7.0起,对广播进行了限制,在8.0后变得更加严格,所以该方法已逐渐被弃用。
“全家桶”拉活
如果有多个自家的app在用户设备上安装,只要开启一个就可以将其他的app唤醒。比如在一个app中发广播,另一个app中收到广播进行拉活。
service系统机制拉活
在service的onStartCommand方法执行完以后,会返回一个int类型的值。这个值有START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT 和 START_STICKY_COMPATIBILITY四种可能。
START_STICKY:粘性。如果service进程被kill掉,保留service状态为开始状态,但不保留传达的intent对象。随后系统会尝试重新创建该service。由于service为开始状态,所以服务创建后一定会调用到onStartCommand方法。 如果此期间内没有任何启动命令被传递到service,那么intent参数为null。
START_NOT_STICKY:”非粘性“。执行完onStartCommand后,服务器被异常kill,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。 执行完onStartCommand后,服务器被异常kill,系统会自动重启该服务,并传入Intent。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版,但不保证被kill后一定执行。
所以,只要将onStartCommand
方法最后返回START_STICKY
即可。
1 | override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { |
某些ROM不会拉活。并且经测试,service第一次被杀死很快被重启,第二次比第一次慢,第三次又比前一次慢,一旦在短时间内被杀死4~5次,则系统不再拉起。
账户同步拉活
官方允许的保活做法!
通过代码的方式,将app列入系统的账户【Account】名单,系统会每15分钟左右进行一次检索,从而将你的app拉活。优点:系统唤醒,比较稳定;缺点:拉活时间不能把控。
JobScheduler拉活
JobScheduler允许在特定状态与特定时间间隔周期性执行任务。我们利用其这个特性开一个定时器即可完成保活,与普通定时器不同的是其调度是由系统完成的。
缺点:比较耗费内存。因为比较流氓,所以被某些ROM禁用了。【不推荐使用】
双进程保活
原理:两个进程协同,一个进程死了,另外一个将其拉活。用到了AIDL在进程间进行交互。