保活与杀活一直以来就是应用于系统间的博弈,魔高一尺道高一丈。各种奇奇怪怪的保活方案层中不穷,但是安卓随着系统版本的迭代,各种杀活策略更加严格,已经把流氓软件的可 *** 作保活方法逼到了角落里面了··········
作为系统杀活阵营支持者的我由于收到应用大佬们十分过分的要求(需要系统拉活他们的应用或服务),所以不得不帮助他们进行系统保活·········
androID系统原生方案
简单的系统保活方案就是防杀和拉活:
1.把要保活的应用加入powersave白名单,这样一般系统在待机模式低电量模式就不会去主动杀应用了。(但是不保证能在lowmemorykiller的屠刀中生存下来) 2020年了,Android后台保活还有戏吗?看我如何优雅的实现!
2.将想要保活的应用设置为特权应用,那么由于特权应用的优先级很高,lowpowerkiller跟影响不到它,并且特权应用系统可以自身拉活它。 Android应用的persistent属性
这一套组合拳打下来,系统绝不会去杀它的,即使意外挂掉,系统也能妥妥的将它拉活。 妥妥的保活
然而········· 应用大佬们并不买账,因为他们想要实现远程OTA应用,所以要允许系统被kill掉,然后再被拉活········ 并且应用大佬写的各种神奇功能的app被设置为特权应用成为持久男人之后,会和系统原生的应用有so兼容性冲突导致各种崩溃,应用不想放弃使用第三方的so,而且特权应用使用webvIEw也有限制。所以导致应用大佬反对特权应用的实现方式········
那么问题就来了,系统自带的保活方案已经无法满足大佬们的要求,就要搞一个曲线救国的方法了。
民间大神方案
翻阅网上的帖子发现一个很有想法的保活方案,双进程native层保活方案,Android进程永生技术终极揭秘:进程被杀底层原理、APP应对被杀技巧
感觉为了保活这些大佬无所不用其极······ 原理不难理解,由于native调用binder的高效性,通过双进程间的文件锁互相感知,其中有一个被kill掉,另一个进程就要将拉活的intent进行发送出去,以对抗系统5ms一次的查杀。虽然原理简单但是实现很复杂啊········ 并且这个是要应用自己实现的,再并且 应用要允许自身OTA被kill掉进程树后被拉起。显然此方案是行不通的······
自己的方案
既然他人的方案行不通,那只有自己想办法实现了。好在系统代码在自己手中,可以在系统中做一些修改来实现应用保活。
起初构想: 实现一个app, 监听开机广播实现自启。然后监测apk被kill状态来拉起被kill的应用。 前提要保证自己开机启动并且自身保活,那么自身要成为特权应用。其次要得到应用被kill的信息,这就犯难了····· 我一个app咋能监测到其他应用被kill的消息?????
于是看了一些文章发现在进程挂掉后会有清理程序:
AMS当然会清理掉其对应的ProcessRecord,这就是cleanUpApplicationRecordLocked()的主要工作。然而,对于persistent应用,cleanUpApplicationRecordLocked()会尝试再次启动对应的应用进程。代码截选如下:
private
final
voID
cleanUpApplicationRecordLocked(ProcessRecord app,
boolean
restarting,
boolean
allowRestart,
int
index)
{
. . . . . .
. . . . . .
if
(!app.persistent || app.isolated)
{
. . . . . .
mProcessnames.remove(app.processname, app.uID);
mIsolatedProcesses.remove(app.uID);
. . . . . .
}
else
if
(!app.removed)
{
if
(mPersistentStartingProcesses.indexOf(app) <
0
) {
mPersistentStartingProcesses.add(app);
restart =
true
;
}
}
. . . . . .
. . . . . .
if
(restart && !app.isolated)
{
mProcessnames.put(app.processname, app.uID, app);
startProcessLocked(app,
"restart"
, app.processname);
}
else
if
(app.pID >
0
&& app.pID != MY_PID)
{
. . . . . .
}
. . . . . .
}
在上面的函数中去将应用被kill的消息发送出去让自己的app去处理,显然发送广播比较简单,但是但觉不是很安全。由于自身应用还要常驻内存,干脆就把它写成系统服务。通过aIDl来将kill后的回收event发送到自己实现的服务中,然后根据名单去拉活应用。自己去维护个白名单的话显然沟通成本比较高效率低下,干脆就让应用调用aIDl接口自己设置。应用自己设置后白名单保存在xml文件中,应用只需设置一次,终身可以拉活。
应用去自己设置白名单,AMS将killevent发送给packagedaemon由其判断是否拉起。同时packagedaemon也向其他服务提供白名单查询接口,这样其他服务的一些权限就可在让应用自己设置了。此服务就是个中转处理,将设置的主导权交还给了应用。
代码写好了后就开始遇到SElinux这个拦路虎了,好在有现成的方法可以参考:
Android : 为系统服务添加 SELinux 权限 (Android 9.0)
Android8.1 新增系统自定义服务一 (SELinux权限)
Android 9.0 (P版本) SystemServer中的服务配置se linux权限
android 8.1 安全机制 — SEAndroid & SELinux
其他参考:
android java进程管理(六)之apk进程的回收
总结
以上是内存溢出为你收集整理的android系统级保活方案全部内容,希望文章能够帮你解决android系统级保活方案所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)