Android 5.1.1系统下手机休眠时监控类应用进程冻结的实现方案咨询
Android 5.1.1 休眠下持续运行监控任务的可落地实现方案
Android 5.1.1(API 22)尚未引入Android 6.0的Doze强制休眠机制,进程休眠后被冻结的核心原因是:系统进入CPU深度休眠态后,会挂起所有未持有有效硬件唤醒锁的进程,普通后台进程的定时逻辑、网络请求、短信触发都会直接暂停,适配逻辑比6.0之后的版本简单很多,可直接落地的实现点如下:
- 用短周期唤醒锁解决CPU休眠挂起的问题
这是解决休眠下逻辑不执行的核心手段,不需要死持唤醒锁造成额外耗电:- 监控逻辑每次准备发起服务器状态检测前,先申请
PowerManager.PARTIAL_WAKE_LOCK类型的唤醒锁,申请时必须设置明确的超时时间(比如设置为60s,覆盖整个检测流程、异常判断、短信发送的全链路时长),所有逻辑执行完毕后主动释放唤醒锁。就算代码崩溃没来得及主动释放,系统到超时时间也会自动回收锁,不会出现永久持锁导致的耗电异常。 - 对应的Manifest权限需要提前声明:
<uses-permission android:name="android.permission.WAKE_LOCK" />,Android 5.1版本中该权限属于普通安装时权限,不需要动态申请,安装后即可生效。
- 监控逻辑每次准备发起服务器状态检测前,先申请
- 用低感知前台服务避免进程被系统回收
Android系统会根据进程的OOM优先级,在内存不足时回收进程,普通后台进程的回收优先级很高,很容易被系统清掉导致监控中断:- 把核心的监控逻辑放在前台服务中运行,按照系统要求在通知栏挂一个常驻通知。Android 5.1没有通知渠道的强约束,可以把通知的优先级调到最低,用极小的图标、简短的文案(比如“监控服务运行中”)降低用户感知,前台服务对应的进程OOM优先级和用户当前交互的应用处于同一层级,基本不会被系统主动回收。
- 不要刻意把服务挪到单独的私有进程(即设置
android:process=":remote"),这类跨进程服务在Android 5.1的各类ROM上反而更容易被判定为孤立后台进程,回收优先级反而更高。
- 用唤醒型闹钟保证定时任务的触发精度
很多开发者在Android 5.1上用普通RTC类型的AlarmManager做定时触发,屏幕熄灭后闹钟完全不触发,本质是普通闹钟在CPU休眠时会被直接挂起:- 设置定时检测任务时,必须选用
RTC_WAKEUP或ELAPSED_REALTIME_WAKEUP类型的闹钟,这类闹钟的触发逻辑不受CPU休眠影响,到点后系统会主动唤醒CPU执行对应的广播回调逻辑。 - 不要依赖系统的重复型闹钟(
setRepeating),Android 5.1对这类重复闹钟有系统级的节流处理,触发间隔不稳定。推荐在每次闹钟触发、执行完所有监控逻辑后,在当前执行流里重新计算下一次检测的时间点,重新设置闹钟——就算进程被意外杀掉,闹钟是由系统AlarmManager服务统一维护的,到点依然会拉起应用执行监控。
- 设置定时检测任务时,必须选用
- 适配国产定制ROM的后台管控规则
多数搭载Android 5.1的国产ROM(如MIUI 7、EMUI 3.1)都在原生系统之外加了自定义的后台冻结逻辑,代码层无法直接绕过:- 首次启动应用时加一步简单的引导,提示用户将应用加入自启动白名单、后台运行权限白名单,避免ROM主动冻结应用进程。
实操避坑:不要用1像素悬浮窗、双进程拉活这类hack手段做保活,这类方式在Android 5.1上很容易被ROM判定为恶意行为,且会大幅提升应用耗电,导致用户主动卸载应用,反而失去长期运行的基础。
内容的提问来源于stack exchange,提问作者jwan
相关产品推荐
相关产品推荐

