4. Doze 模式深度阶段:静止进入深休眠、维护窗口、定期退出
核心概念
当设备进入轻度 Doze 后,如果继续保持屏幕关闭且完全静止状态超过一定时间(通常为 30 分钟至 1 小时不等,取决于设备策略与电量水平),系统会进一步收紧限制,进入深度 Doze(Deep Doze / IDLE)阶段。此阶段被视为 Android 节电策略的最终防线,意在最大化延长待机时间。
- 网络彻底切断: 所有应用的网络访问权限被冻结,包括前台通知推送和后台数据同步。
- Wakelock 失效: 应用持有的部分 Wakelock 将被系统忽略,强制 CPU 进入深度睡眠。
- Alarm 延迟: 应用设置的普通闹钟被统一延迟,直到下一个维护窗口到达。
- Job/同步挂起: JobScheduler 和 SyncAdapter 任务完全暂停。
⚠️ 重点提示: 深度 Doze 不会杀死应用进程或强制回收内存。它只是冻结应用获取资源的能力(网络、CPU锁、高精度定时器)。应用进程本身仍然驻留在内存中,一旦退出 Doze 即可恢复运行。
类比说明:冬眠的棕熊
想象一头棕熊在冬季进入树洞深眠(深度 Doze)。它几乎不消耗能量,不外出觅食,对外界刺激反应极低。但为了维持基本生命体征,它每隔一段时间会短暂苏醒(维护窗口),调整姿势、检查环境,然后继续沉睡。如果有人用力敲打树洞(高优先级推送 / 闹钟),它也可能被迫提前退出休眠。
- 轻度 Doze 相当于打盹: 耳朵还在动,稍有动静就能醒来。
- 深度 Doze 相当于深睡: 呼吸和心跳极慢,不到万不得已不会醒来。
- 维护窗口相当于伸懒腰: 短暂恢复机能,处理积压任务,然后继续睡。
原理图解:深度 Doze 状态机
下图呈现了从轻度 Doze 转入深度 Doze,以及维护窗口与退出的完整闭环流程。
常见误区辨析
| 误区 | 真相 |
|---|---|
| 深度 Doze 会杀死后台应用 | 不会。深度 Doze 只冻结资源(网络、定时器),应用进程仍在后台运行,只是无法执行实际操作。 |
| 所有闹钟在深度 Doze 下都被延迟 | 部分闹钟可绕过:setAlarmClock() 触发的闹钟会强制退出 Doze;高优先级 FCM 推送也可以唤醒设备。 |
| 只要连接 Wi-Fi 就不会进入深度 Doze | Wi-Fi 连接本身不会阻止进入深度 Doze。保持屏幕关闭且静止才是关键条件。Wi-Fi 在深度 Doze 下也会被限制扫描。 |
练习题
- (选择题) 以下哪种场景会强制设备退出深度 Doze?
A. 应用发起普通 HTTP 请求
B. 应用通过AlarmManager.setExact()设置闹钟
C. 系统检测到用户拿起手机(显著移动)
D. 蓝牙一直连接中 - (简答题) 为什么维护窗口的时间窗口仅有 1% 左右?这样设计的目的是什么?
- (Bug 修复) 用户反馈步数记录 App 在夜间深度 Doze 期间完全不记步,即使申请了 PARTIAL_WAKE_LOCK 也无用。请从深度 Doze 的原理角度分析原因。
- (代码分析) 以下代码在深度 Doze 期间执行会返回什么?
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); boolean isIdle = pm.isDeviceIdleMode(); // 此时 isIdle 的值是? Log.d("PowerTest", "Device is idle: " + isIdle);
应用边界
- 白名单机制: 系统内置
config_ignoreBatteryOptimizationWhitelist名单(如 GMS、Launcher、输入法),这些应用在深度 Doze 下保留受限的网络访问能力。 - FCM 高优先级: 服务器推送时需要设置
"priority": "high",客户端才能在深度 Doze 下收到唤醒广播(仍存在一定延迟,受sync_delay影响)。 - JobScheduler 约束: 即使应用被白名单,JobScheduler 在深度 Doze 期间也不会严格按照 deadline 执行,必须等待维护窗口或退出 Doze。
- Debug 命令(仅供开发测试):
# 强制进入深度 Doze(需要 root 或调试权限)
adb shell dumpsys deviceidle force-idle
# 设置空闲超时时间(单位毫秒)
adb shell dumpsys deviceidle step
# 查看当前 Doze 状态
adb shell dumpsys deviceidle enabled