安卓进程保活方案记录(双重fork+文件锁+手搓parcel)

最近看到一个安卓保活的文章,挺震惊的,都2026年还能搞保活,记录一下。

从文章来看应该是字节和腾讯都用了这种方案,核心上是一样的。

1.双重fork

进程保活首先要解决一个问题,进程被杀了谁来重新唤起。此方案采用子进程唤醒的方式重新拉起主进程,但是安卓8.0之后,应用进入后台后,系统可能杀死主进程及其所有子进程,所以需要想办法解决这个问题。

在Linux/Android中,父进程死亡后,子进程会由init进程接管,即其父进程变成init,通过这种方法使子进程逃逸出进程组,即其与原先的父进程没有关系了,这样子就不会被一锅端掉。

实现方法是native层fork一个子进程,子进程在fork一个孙进程,然后将子进程exit,这样子孙进程就成功逃逸了。

2.监听父进程死亡

逃逸出来的进程需要知道父进程是否死亡,然后在其死亡时唤醒父进程。查询父进程是否还在,可以访问 /proc/ 目录,看当前系统的进程有哪些,但是轮询显然太耗电且容易被查杀。这个方案巧妙使用了锁的机制。

首先父进程一开始对一个文件进行加锁,逃逸出来的子进程尝试对同一个文件进行flock,由于互斥锁的存在,此进程会被内核挂起阻塞(或者 usleep 轮询),不占用 CPU 资源;如果父进程死亡,操作系统回收其文件句柄,那么子进程被唤醒拿到锁,这时代表父进程被杀,需要唤起父进程。

3.手搓ipc数据包(Parcel)拉起app

当子进程发现主进程死亡后,如果通过常规的 am start 命令行去拉起,不仅速度慢,而且极易被高版本 Android 的后台拦截机制阻断。

此方案在native层引入了NDK 的 AIBinder API,徒手拼接底层 IPC 数据包(Parcel),提前在内存中组装好了一个向 ActivityManagerService 发送 startInstrumentation 事务的 Parcel 包。触发时,直接调用 AIBinder_transact 将伪造的请求发给 AMS。系统接收到请求后,会主动分配进程资源,拉起该 APP 注册的自定义 Instrumentation。应用随之在 callApplicationOnCreate中启动,完成唤起。

在主进程死亡后伪造合法请求,触发 AMS 重新分配进程并拉起自定义 Instrumentation,从而实现隐蔽唤醒。

相关推荐
成都大菠萝10 小时前
Android Car CarProperty 车辆信号链路
android
敲代码的鱼10 小时前
PDF 预览与签名批注写回 支持安卓 iOS 鸿蒙 UTS插件
android·前端·ios
时光足迹12 小时前
uni-app 视频通话实战:康复师与患者视频问诊的 6 个致命 Bug 与解决方案
android·ios·uni-app
Coffeeee16 小时前
闲聊几句,Android老哥们,你们多久没做技改需求了
android·程序员·代码规范
萝卜er17 小时前
Fragment 生命周期与状态恢复-《Android深水区(四)》
android
萝卜er17 小时前
Intent 显式、隐式与 PendingIntent-《Android深水区(五)》
android
Kapaseker19 小时前
一文吃透 Kotlin 集合操作符
android·kotlin
三少爷的鞋20 小时前
Main-safe:现代Android 架构真正的分水岭
android
沐怡旸1 天前
深入解析 Android Performance Analyzer (APA) 底层架构与技术原理
android
李斯维1 天前
从历史的角度看 Android 软件架构
android·架构·android jetpack