这是一个轻量级的库,配置几行代码,就可以实现在android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下,clean master获取root权限下都无法杀死进程
支持系统2.3到6.0
支持大部分设备,包括三星,华为,oppo,nexus,魅族等等
可以简单对开机广播进行保护
github地址:
https://github.com/Marswin/MarsDaemon
原理分析:
Android 进程常驻(0)----MarsDaemon使用说明
Android 进程常驻(1)----开篇
Android 进程常驻(2)----细数利用android系统机制的保活手段
Android 进程常驻(3)----native保活5.0以下方案推演过程以及代码详述
Android 进程常驻(4)----native保活5.0以上方案推演过程以及代码详述
Android 进程常驻(5)----开机广播的简单守护以及总结
正文:
上一篇我们通过父子进程间建立双管道,来监听进程死掉,经过测试,无耗电问题,无内存消耗问题,可以在设置中force close下成功拉起,也可以在获取到root权限的360/cleanmaster下成功存活。
4.4.3的ActivityManagerService
实现在这里
然后5.0的AMS
实现
开始自己头脑风暴,想出以下几种解决策略:
1、放弃java进程,使用两个纯native的binary进程,相互保活,确保native进程常驻,然后按时拉起需要常驻的java进程。
2、使用setsid将子进程的session改变,是否可以让系统不冻结子进程。
3、子进程创建子进程,然后自杀,重复1000次,也就是父进程和自己子进程的子进程的子进程重复一千遍的进程之间互保,是否可以让系统不冻结子进程其中a和b两个进程都会执行这块代码,对于a进程来说,indicator_self_path对应a1,indicator_daemon_path对应b1,observer_self_path对应a2,observer_daemon_path对应b2,b进程同理
首先自己加锁,然后加入同步模块notify_and_waitfor
以上代码就是上述同步逻辑
同步完成后,两个进程同时监听对方的锁,一方挂掉另一方立刻可以监听到。这套方案在5.0+上可以做到互相监听对方死亡状态,因为都是阻塞方法,所以无耗电效率问题。
这里要说一下,也许你看完源码你会问为什么步在5.0以下采用这种方案,因为这种方案是需要挂两个进程的,虽然与父子进程相比,在linux下都是两个进程两个pid,但是在android系统的设置里面,父子进程中的native进程是android系统统计不到的,所以不会列出来,不会让用户觉得你为啥启这么多进程。所以从用户体验角度,5.0以下还是采用上一篇博文采用的方案。
所以时间很重要!!!我们要跟系统抢时间
那么现在的问题是怎样才能把intent发出去,查看源码,我们可以看出intent的发送实际上是ActivityManagerNative这个类,他持有一个binder,用来与系统的ActivityManagerService通信,然后我们发送intent的时候会初始化一个Parcel,通过binder transcate过去。
时间都消耗在了pacel的创建上。
那么我们可不可以把这些耗时操作放在进程开始的时候就完成,等到监听到进程挂掉,直接调用。
但是那个binder我们没法直接拿到,这里需要用到反射。
看代码:
代码com.marswin89.marsdaemon.strategy.DaemonStrategy22.java
拿到ActivityManagerNative实例然后拿binder,也就是他的一个成员变量mRemote
然后把Pacel初始化出来,这里注释掉的是我一行一行试验的,为了节省时间,在能达到目的的前提下,时间越少越好,所以参数能少传就少传。
然后在检测到对方进程死掉的时候,直接调用transcate方法。
ok,5.1上也可以实现双向守护。
但是很遗憾,6.0上又跪了。
然后经过排查,发现通过以上方式用binder transcate的方法无法启动一个service。那该怎么办呢?抱着试试看的心里尝试了broadcastreceiver,果然广播是可以的。同样的原理用ActivityManagerNative中的binder transcate一个pacel来启动一个broadcast拉起进程。
也是仿照系统源码来做的广播的Pacel
代码com.marswin89.marsdaemon.strategy.DaemonStrategy22.java
ok,6.0也搞定。
在系统force close时成功拉起对方,但是在360\clean master with root的强杀下仍然有一定的几率会跪。通过log可以看出来,在一键清理的时候是有成功拉起的,但是360\cm均会重复杀,被拉起来的新进程还没初始化完成,就又被杀掉了。
再次,时间很重要!!!我们要跟360\cm抢时间
这里我们在进程刚创建的时候使用多线程,将文件的同步加锁监听与启动另一个进程同时进行,从来能节约100毫秒左右的时间
大功告成!
从5.0到6.0,在force close和360\cm with root的一键清理下都可以实现互相守护了。