Android 保活机制详解 —— 从概念到实践

25 阅读5分钟

Android 保活机制详解 —— 从概念到实践

记录在 3568主板 人脸支付终端上对接设备 SDK,实现 App 保活的全过程。


一、背景

我们的 App 跑在 3568 人脸支付终端上,这是一个无人值守的自助点餐机。在这种场景下,App 必须7×24 小时稳定运行,不能出现"App 挂了没人知道,客人来了点不了餐"的情况。

这就要求 App 具备"保活"能力。


二、保活 ≠ 自启动,很多人搞混

这是最容易混淆的两个概念:

对比项开机自启动保活(Keep-Alive)
触发时机只在开机瞬间触发一次持续监控,每隔 N 秒检测一次
App 崩溃后❌ 不会自动拉起来✅ 自动重启
被系统杀掉后❌ 不会自动拉起来✅ 自动重启
按 Home 回到桌面✅ 进程还在,不会干预
切到系统设置✅ 正常后台切换不受影响

简单理解:

  • 自启动只管"开机那一下",开完就不管了。
  • 保活像一个保安,24 小时盯着你的 App,发现不在了就立刻拉回来。

三、普通 Android 搞保活有多难

在标准 Android 系统上做保活,基本是地狱模式:

1. 常规手段(基本没用)

// 方式1:双进程守护 —— 两个 App 互相监控,被杀一个另一个拉回来
// 问题:Android 5.0+ 系统会一起杀,双进程同归于尽

// 方式2:前台 Service + 常驻通知栏
startForeground(NOTIFICATION_ID, notification);
// 问题:通知栏挂在那里用户看着烦,而且某些 ROM 还是会杀

// 方式3:1 像素 Activity
// 问题:Android 8.0+ 后台限制,几乎无效

// 方式4:JobScheduler / WorkManager 定时唤醒
// 问题:间隔越来越长(Doze 模式),最终可能几小时才唤醒一次

2. 为什么这么难

  • Android 8.0+ 引入了后台执行限制,App 在后台跑 Service 受到严格管控。
  • Android 9.0+ 引入 App Standby Buckets,不常用的 App 几天才能唤醒一次。
  • 各大厂商(华为/小米/OPPO/vivo)还有自己的省电策略,比原生更激进。

结论:普通 App 想在标准 Android 上做真正可靠的保活,基本不可能。


四、为什么我们的设备可以?

因为我们用的是定制系统设备

3568 设备基于 Rockchip 平台,系统层面内置了 QZhengIFManager 服务,提供了系统级的保活接口:

// 设备 SDK 提供的保活接口
new QZhengIFManager(context).setMonitorApp(packageName, true, intervalSeconds);
  • packageName — 要守护的 App 包名
  • true — 开启监控
  • intervalSeconds — 检测间隔(秒),比如填 5 就是每 5 秒检查一次

这背后是系统级的守护进程在工作,不是 App 自己在挣扎,所以非常可靠。


五、实际操作:代码怎么加

5.1 引入 SDK

把设备 SDK 提供的 q-zhenglib.aar 放到 android/app/libs/ 目录下。

build.gradle 中已有自动加载配置:

implementation fileTree(dir: "libs", include: ["*.aar"])

所以放进去就能用,不需要额外配置。

5.2 在 MainActivity 中初始化

选择放在 MainActivity.onCreate(),因为这个 SDK 需要 Activity 上下文:

import com.q_zheng.QZhengIFManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
  
    // ... 其他初始化代码 ...
  
    // 只在对应用设备上启用保活
    if (is3568FacepayDevice(...)) {
        try {
            boolean result = new QZhengIFManager(this)
                    .setMonitorApp(getPackageName(), true, 5);
            Log.i("MainActivity", "setMonitorApp result = " + result);
        } catch (Throwable e) {
            Log.e("MainActivity", "setMonitorApp failed", e);
        }
    }
}

5.3 为什么要判断设备型号

你的 APK 可能运行在三种设备上:

设备型号标识有 QZhengIFManager 吗
Pad 平板k62v1_8s / alps❌ 没有
工位机3576SE / Shimeta❌ 没有
人脸支付终端xf108fw-y / rk3568✅ 有

如果不做判断,在 Pad 或工位机上运行时会因为找不到 QZhengIFManager 类而崩溃。

5.4 为什么不走 RN 桥接?

因为保活是一次性设置,App 启动时调一次就行,后续不需要 JS 层关闭或切换。直接放在原生 onCreate() 最简单可靠。

如果你的场景需要在设置页开关保活、动态改间隔,那才需要做 React Native 桥接。


六、常见疑问解答

Q1:保活后 App 能退到后台吗?

可以。保活监控的是进程是否存活,不是"是否在前台"。你按 Home 回桌面、进系统设置,进程还活着,不会被强制拉回前台。

Q2:开机后 App 会自己启动吗?

会。setMonitorApp 是告诉系统守护进程"帮我盯着这个 App"。开机后守护进程检测到 App 没在运行,会自动拉起来。插电开机即可,不用人点。

Q3:被人手动强制停止呢?

这取决于设备实现。多数这类 SDK 的守护进程运行在系统层面(system_server),即使你在设置里"强制停止"App,守护进程仍会检测到并重新拉起。

Q4:5 秒检测一次耗电吗?

不耗电。这是进程存活状态检查,不是 CPU 密集型操作。对于常年插电的人脸支付终端,功耗完全不是问题。


七、总结

知识点一句话
保活 vs 自启动自启动只管开机那一下,保活是持续守护
标准 Android几乎没有可靠的保活手段,系统省电策略通常很激进
定制设备优势设备提供系统级守护接口,可靠且简单
实战落点放在 MainActivity.onCreate(),仅 3568 设备执行
不需要桥接一次性设置,不需要 JS 开关,原生做了最省事

一句话记住:保活就是系统帮你盯着,App 死了就立刻叫醒。对无人值守设备来说这是必需能力,对定制安卓设备来说通常是现成能力。