进程保活介绍

进程保活

进程保活

进程保活的方式分为两个层面:提高进程优先级,降低被杀死概率在进程被杀死后进行拉起

补充:先区分目标“保活率”与“任务完成率”。

  • “进程一直活着”不是唯一目标,业务上更关键的是“任务最终完成”。
  • 对即时任务可用前台Service;对延迟任务优先WorkManager/JobScheduler

1. 进程的优先级

进程优先级

优先级最低的进程首先被杀死、进程的等级会因为其他进程的依赖而提高一个进程服务于另一个进程,则它的优先级不会比它服务的进程优先级低

按重要性分类:

  • 前台进程:进程持有一个正在与用户交互的Activity或者和交互Activity绑定的Service,前台运行的Service(执行startForeground()),执行onReceive()的BroadcastReceiver
  • 可见进程:进程持有一个被用户可见但没有显示在最前端的Activity(调用到了onPause())或者和可见Activity绑定的Service
  • 服务进程:进程持有一个startService()启动的Service进程,例如播放音乐,下载文件等Service
  • 后台进程:进程持有一个用户不可见的Activity(调用到onStop()没有到onDestroy()),进程被存放在一个LRU列表中,即很长时间没用的Activity会被优先杀死
  • 空进程:进程不包含任何活跃的应用组件,唯一的作用是为了缓存需要,缩短下次启动的时间

2. Android进程回收策略

对于进程的回收,早期主要依靠LowmemoryKiller,现代Android更多由lmkd结合oom_score_adj进行回收决策。

进程级别

红色代表易被杀死的进程,绿色不易被杀死。LowmemoryKiller会优先杀死OOM_ADJ较大的进程,优先级相同则进一步受到进程所占内存和进程存活时间的影响。

3. 提升进程优先级

  • 前台Service(推荐):通过startForegroundService() + startForeground()提升进程优先级,是当前最可控、最合规的常见方式。
    • 注意点:前台Service必须展示用户可见通知,不能依赖“隐藏通知”方案规避。
    • 版本约束:Android 8.0+ 对后台启动和前台服务启动时机有更严格限制。
  • 一像素Activity方案(不推荐):历史上曾用于提升优先级,但在新系统和厂商ROM中稳定性差,且容易触发合规风险与用户体验问题。

4. 进程死后拉活的方案

补充:Doze与App Standby会影响拉起效果。

  • 设备进入Doze后,网络与闹钟触发会被批处理,定时任务会明显延后。

  • 需要精确定时时可评估setExactAndAllowWhileIdle(),但调用频率受系统严格限制。

  • 利用系统广播拉起:在发生特定事件时,系统会发送相应广播。可在AndroidManifest静态注册部分广播接收器,在事件发生时触发应用拉起。常见广播事件如下:

    • 开机广播:RECEIVE_BOOT_COMPLETED
    • 网络变化:CHANGE_NETWORK_STATE,CHANGE_WIFI_STATE…
    • 文件挂载:MOUNT_UNMOUNT_FILESYSTEMS
    • 屏幕亮灭:SCREEN_ON,SCREEN_OFF
    • 锁屏解锁:RECEIVE_USER_PRESENT
    • 应用安装卸载:PACKAGE_ADDED,PACKAGE_REMOVED
      缺点:
    • Android 8.0+ 对隐式广播有较多限制,很多历史广播无法再稳定触发。
    • 广播接收器容易被系统“自启动管理”限制,拉起成功率不可控。
  • 利用第三方应用广播拉起(不推荐):监听第三方应用广播进行互拉在新系统中可持续性差,且存在明显合规风险。
    缺点:

    • 需要维护成本高,版本兼容性差。
    • 第三方广播随版本更新可能被修改或移除。
  • 利用Service重启策略:把Service返回值设置为START_STICKY,在进程被系统回收后可提高被重建概率。
    缺点:

    • 不保证一定重启,且受后台限制、厂商策略和系统负载影响。
    • 被用户force stop后不会自动恢复。
      补充:START_STICKY表示“被系统回收后可尝试重建”,不等于“永不被杀”。
  • 利用Native进程守护(不推荐):通过fork创建守护进程监控主进程,历史上在低版本有效,但新系统下成功率和合规性都较差。
    适用范围:

    • Android 5.0以下历史版本效果相对明显。
    • Android 5.0+ 后受系统与厂商策略影响,force stop场景下同样无法保证恢复。
  • 利用JobScheduler调度任务(推荐):Android 5.0+ 提供JobScheduler,适合做延迟任务与周期任务。
    适用范围:Android 5.0+;执行时机受系统调度与省电策略影响。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public class KeepLiveService extends JobService {

    private final static String TAG="KeepLive";

    private volatile static Service mKeepLiveService= null;

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
    return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
    return false;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public void startJobscheduler(){
    try {
    int jobId=1;
    JobInfo.Builder builder=new JobInfo.Builder(jobId,
    new ComponentName(MyApplication.getApplicationContext(),
    KeepLiveService.class));
    builder.setPeriodic(15 * 60 * 1000L);//系统有最小周期限制,通常不小于15分钟
    builder.setPersisted(true);//重启后需要继续执行
    JobScheduler js = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
    js.schedule(builder.build());
    }catch (Throwable e){
    e.printStackTrace();
    }
    }
  • 利用WorkManager(推荐):面向“任务完成”目标时,优先使用WorkManager,内部会按系统版本适配到JobScheduler/AlarmManager等能力。

  • 利用账号同步机制拉起(历史方案):账号同步机制可触发定期执行,但在新系统中适用范围明显缩小。
    适用范围:旧版本可用,Android N后限制增强。

  • 其他方案

    • 使用厂商推送通道(如小米、华为、OPPO、vivo)提升消息到达率。
    • 结合电池白名单与自启动设置引导(需明确用户授权)。

实践建议:

  • 优先使用系统推荐组件(前台Service、WorkManager、JobScheduler)。
  • 对保活相关行为做可观测:记录唤醒来源、任务完成率、设备品牌/系统版本分布。
  • 避免依赖灰色互拉、隐藏通知等高风险方案。

进程保活介绍
https://leo-wxy.github.io/2018/04/12/进程保活介绍/
作者
Leo-Wxy
发布于
2018年4月12日
许可协议