Doze模式是自Android 6.0开始引入的两项省电功能的其中之一,还有一个就是appstandby,通过管理应用在设备未连接至电源时的行为方式,帮助用户延长电池寿命。当用户长时间未使用设备时,低电耗模式会延迟应用的后台 CPU 和网络活动,从而降低耗电量。应用待机模式会延迟用户近期未与之交互的应用的后台网络活动。
当设备处于低电耗模式时,应用对某些高耗电量资源的访问会延迟到维护期。如果用户未插接设备的电源,在屏幕关闭的情况下,让设备在一段时间内保持不活动状态,那么设备就会进入低电耗模式。在低电耗模式下,系统会尝试通过限制应用访问占用大量网络和 CPU 资源的服务来节省电量。它还会阻止应用访问网络,并延迟其作业、同步和标准闹钟。系统会定期退出低电耗模式一小段时间,让应用完成其延迟的活动。在此维护期内,系统会运行所有待处理的同步、作业和闹钟,并允许应用访问网络。
在每个维护期结束时,系统会再次进入低电耗模式,暂停网络访问并推迟作业、同步和闹钟。随着时间的推移,系统安排维护期的次数越来越少,这有助于在设备未连接至充电器的情况下长期处于不活动状态时降低耗电量。
一旦用户通过移动设备、打开屏幕或连接至充电器唤醒设备,系统就会立即退出低电耗模式,并且所有应用都会恢复正常活动。
在低电耗模式下,您的应用会受到一下限制:
- 暂停访问网络
- 系统忽略唤醒锁定
- 标准 Ala'r'm'Manager闹钟(包括
setExact()
和setWindow()
)推迟到下一个维护期 (如果您需要设置在设备处于低电耗模式时触发的闹钟,请使用setAndAllowWhileIdle()
或setExactAndAllowWhileIdle()
,使用setAlarmClock()
设置的闹钟将继续正常触发,系统会在这些闹钟触发之前不久退出低电耗模式) - 系统不执行 WLAN 扫描
- 系统不允许运行同步适配器
- 系统不允许运行
JobScheduler
测试相关:
运行以下命令,强制系统进入doze模式
adb shell dumpsys deviceidle force-idle
准备就绪后,运行以下命令,使系统退出闲置模式
adb shell dumpsys deviceidle unforce
执行以下命令,重新激活设备
adb shell dumpsys battery reset
以上介绍内容来自:
https://developer.android.com/topic/performance?hl=zh-cn
代码实现简介(基于android R):
Doze模式的控制代码都在DeviceIdleController中,DeviceIdleController作为一个系统服务在systemserver中启动,启动后监听电池广播/应用卸载广播/屏幕亮灭广播,还通过注册传感器监听来获知当前设备是否在请求未知信息,是否有运动,来确定当前设备状态,是否需要进入doze模式。进入doze模式后通过NetworkPolicyManagerService来修改联网策略,通过BatteryStatsService修改电池省电策略,通过PowerManagerService来修改持锁策略,且通过发送广播DEVICE_IDLE_MODE_CHANGED来通知对应的省电模块和jobschedule模块做出相应调整。
Doze模式状态图如下:
Doze模式状态流转如下图:
DeviceIdleController根据不同状态做不同的检测,设置不同的闹钟时间间隔,在最后强制设备进入doze睡眠模式,且会在进入后一段时间自动的退出doze模式,短暂退出后会再次进入,且距离下次退出doze模式时间会逐次拉长。在任意一个非STATA_ACTIVE状态下,如果接收到亮屏或者充电广播,或者是注册的传感器监听到运动信息,都会直接将状态回退到STATE_ACTIVE状态,所以进入