KeepAlive

Project Url: lcodecorex/KeepAlive
Introduction: Fighting against force-stop kill process on Android with binder ioctl / Android 高级保活
More: Author   ReportBugs   
Tags:

KeepAlive 是在Leoric(通过 JNI 复活进程)的基础上,实现了通过 ioctl 复活进程,能最大程度提高复活率。

master分支是利用 libbinder.so 与 ActivityManagerService 通信的版本,ioctl分支是使用 ioctl 与 binder 驱动通信的版本。

  1. 该项目仅供学习和参考,在 android4.4 到 android9.0 的模拟器上有效,在真机上不能保证保活成功(MIUI 等定制系统已封杀了这个方案)。
  2. 对于自研轻量定制的 Android 系统,对一些系统应用的保活,这个方案还是很有优势的。资源占用少,用户无感知,成功率高。
  3. 不建议在 C 端产品上使用。
  4. 可作为学习 binder 框架的一个案例。

使用方法

  1. 在 Application 中注册 KeepAlive 服务

    @Override
    protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     KeepAliveConfigs configs = new KeepAliveConfigs(
                     new KeepAliveConfigs.Config(getPackageName() + ":resident",
                             Service1.class.getCanonicalName()));
     KeepAlive.init(base, configs);
    }
    
  2. Service1 对应的进程名是":resident",或者其它任意命名

    <service
     android:name="Service1"
     android:process=":resident" />
    

    Service 需要继承 KeepAliveService,否则在 Android4.4 上将没有保活效果。

  3. 在合适的地方,启动 Service1,它将自动唤醒保活进程

    startService(new Intent(MainActivity.this, Service1.class));
    

    如果需要服务自启动,看第 6 条。

  4. 忽略电池优化

    configs.ignoreBatteryOptimization();
    
  5. 防止短时间内重复启动

    // 配置短时间重启限制,每次重启间隔限制是 10s,最多允许 3 次 10 秒内的连续重启
    configs.rebootThreshold(10*1000, 3);
    

    注:保活和重启限制相违背,更准确的应该做崩溃重启限制。

  6. 设置应用自启执行的操作

    configs.setOnBootReceivedListener(new KeepAliveConfigs.OnBootReceivedListener() {
     @Override
     public void onReceive(Context context, Intent intent) {
         // 设置服务自启
         context.startService(new Intent(context, Service1.class));
     }
    });
    

实现原理

应对方法

下面是一种简单的方法杀死 KeepAlive:

ps -A | grep `ps -A | grep keepalive | awk '{print $1}' | head -1` | awk '{print $2}' | xargs kill -19 && am force-stop com.boolbird.keepalive

对于系统有两种思路可以选择:

  1. 加入在 force-stop 期间不允许启动新的进程的逻辑
  2. 修改 force-stop 的杀进程逻辑为:预先收集好所有进程再进行 kill(如有必要还可以先发送 SIGSTOP)

测试

项目根目录下的 kill_alive.sh 用于重复杀进程测试。

问题

1、怎么保活多个进程 2、避免在 Application 中初始化第三方库,避免在所有进程都初始化第三方库

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools