- 由 b178903294创建, 最后修改于12月 30, 2020
上回书说到android的powersave lowmemorykiller 等的后台清理机制,与系统如何保证应用不被杀掉的保活方案。我们为了自己的应用能够常驻后台提供了系统保活的机制。那么其他三防应用为了自己能够永生,各种手段无所不用其极,绕过各种系统的杀活机制来达到常驻后台干些见不得人的勾当。所以我们常常见到系统运行的好好的突然各种弹窗,突然的cpu占用飙升猝不及防的卡死········ 即使我们信任的各种学习app后台罪行也是罄竹难书。
基于此,我们必须要想办法就惩治这些流氓,那必须的要拿出方案来解决这个棘手的问题。不巧,这个活儿被鄙人接下了。那么咱们先研究一下应用自启的原理吧,知己知彼百战不殆,知道他们的犯罪方法才能有针对性的防治。
一、应用自启常见套路
1.接收各种广播
原理就不多说了,网上很多文章都已经说过了,核心就是因为 Android 系统在很多时刻都会给所有的应用广播消息,比如 系统开机、电量低,网络状态变化等,只需自己静态注册广播接收者,然后接收系统发出的广播消息然后处理即可。
android.intent.action.BATTERY_CHANGED | 持久的广播,包含电池的充电状态,级别和其他信息。 |
android.intent.action.BATTERY_LOW | 标识设备的低电量条件。 |
android.intent.action.BATTERY_OKAY | 标识电池在电量低之后,现在已经好了。 |
android.intent.action.BOOT_COMPLETED | 在系统完成启动后广播一次。 |
android.intent.action.BUG_REPORT | 显示报告bug的活动。 |
android.intent.action.CALL | 执行呼叫数据指定的某人。 |
android.intent.action.CALL_BUTTON | 用户点击"呼叫"按钮打开拨号器或者其他拨号的合适界面。 |
android.intent.action.DATE_CHANGED | 日期发生改变。 |
android.intent.action.REBOOT | 设备重启。 |
防治办法:禁掉接收这些广播的注册的activity
2.被其他全家桶应用拉活
此处典型的有:腾讯全家桶、百度全家桶、360全家桶、阿里系、抖音系、美团系·········
防治此类的方法就是能在google play下载的应用,绝对不要去国内的应用商城下载。(原理是,google play对应用各种都有严格限制,重点是应用互相拉活大多时候是为了推送广告,谷歌会要求广告进行分成)
3.系统账户同步机制拉活
手机系统设置里会有Account帐户一项功能,任何第三方APP都可以通过此功能将我们自己的APP注册到这个Account帐户中,并且将数据在一定时间内同步到服务器中去。系统在将APP帐户同步时,自动将未启动的APP进程拉活,具体操作参见Google官方demo。
4.JobSchedule 机制拉活
JobScheduler允许在特定状态与特定时间间隔周期执行任务,所以我们也可以利用它的这个机制来完成拉活的功能,其效果就像是开启一个定时器,与普通定时器不同的是其调度由系统完成,也比较可靠稳定,但是会受到白名单等模式的影响,在某些ROM中甚至无法拉活。
5.其他和混合自启拉活
终极版就是该应用集合和所有的拉活自启方案。
二、应用保活常见套路
1.提升优先级 设为前台服务 (前排采坑: camera自动升级失败问题)
2. 1像素前台保活,由于前台可见activity系统为了保证用户体验,提升到了最高优先级,所以系统不会主动杀掉前台有显示界面的app
3. 循环播放无声音乐 原理同上
4. 利用系统Service机制拉活 将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后拉活
5. 利用 Native 进程拉活 多进程守护 互相拉活
三、解决思路和方案
1.针对应用开机自启的应用,我们采用传统的disable掉其在AndroidManifest.xml中声明的activity。 那么我们怎么查询哪些activity声明了android.intent.action.BOOT_COMPLETED呢,这时候packageManager就尅一派上用场了。
|
ps: pms里面有很多的queryIntent* 的查询方法,可以查询各种类型的activity和service, 都是很好用的查询工具
2.针对后台自启的应用,我们又要梳理一下后台启动流程了
先丢一张流程框架图:
我们启动服务的时候使用startService方法,其直接调用:
frameworks/base/core/java/android/app/ContextImpl.java
|
ContextImpl中只做了validateServiceIntent校验(target 21之后限制隐式启动),然后调用了AMS的startService方法。再看AMS中的实现:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
|