前言
从Android 6.0开始,谷歌引入了Doze模式(打盹模式)的省电技术延长电池使用时间。如果用户长时间未使用设备,低电耗模式会延迟应用后台 CPU 和网络活动,从而延长电池续航时间。根据第三方测试显示,两台同样的Nexus 5,开启的Doze的一台待机能达到533小时,而未开启Doze的一台待机只能达到200小时。Doze省电效果十分明显。
Doze省电技术原理
Doze模式细分light idle和deep idle,本文主要介绍deep idle
操作 | 低电耗模式-deep idle | 轻度低电耗模式-light idle |
触发器 | 屏幕关闭、电池供电(未插电)、静止 | 屏幕关闭、电池供电(未插电) |
计时 | 随维护时段依次增加 | 随维护时段反复持续 N 分钟 |
限制 | 无法访问网络、唤醒锁定和 GPS/WLAN 扫描;闹钟和作业/同步被延迟 | 无法访问网络;作业/同步被延迟(维护窗口除外) |
行为 | 仅接收优先级较高的推送通知消息 | 接收所有实时消息(即时消息、致电等);优先级较高的推送通知消息可以暂时访问网络 |
退出 | 动作、屏幕开启或闹钟响铃 | 屏幕开启 |
Doze技术原理主要分为状态机+省电管控(后台 CPU 和网络活动)措施,延长待机续航的效果。
其中状态机的目的主要识别用户长时间未使用设备场景并标记Idle状态,省电管控措施主要是Idle状态内限制应用后台 CPU 和网络活动
1.DeepIde状态机
为了更好地识别用户未使用场景,Doze模式设计了状态机机制,主要包含长期灭屏、无运动、无显著运动、无GPS变化的状态检测与流转。其中运动检测和GPS侧重的是静止状态的识别。
1.1 DeepIde状态机时序图
待机灭屏时会先开启一个30分钟的闹钟检测灭屏状态持续30分钟,满足灭屏待机30分钟后,再开启30分钟的低功耗运动检测查看是否为静止状态,满足30分钟保持静止状态后,再开启4分钟的高精度ACC动作检测是否是绝对静止状态,满足4分钟持续的绝对静止状态后,再开启30秒的GPS定位检测是否没有定位变化,满足30秒没有定位条件,就可以进入deep idle状态,对可以放心对操作系统层上的应用进行功耗限制了。
// 30分钟的待机灭屏时长检测定义
private long mDefaultInactiveTimeout =
(30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
// 30分钟的低功耗普通运动检测
private long mDefaultIdleAfterInactiveTimeout =
(30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
// 4分钟的高耗电高精度的ACC运动检测
private long mDefaultSensingTimeout =
!COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L;
// 30秒的GPS位置检测
private long mDefaultLocatingTimeout =
!COMPRESS_TIME ? 30 * 1000L : 15 * 1000L;
从上述时序图可以看出,进入deep idle需要1小时4.5mins,idle周期时间为1小时、2小时、4小时、最大6小时,维护窗口时间为5mins。
移动检测:主要分为SIGNIFICANT_SENSOR检测和加速度传感器检测,区别是一个低功耗精度没那么高和一个高功耗精度高
1.2 DeepIde 状态机流转图
注:QUICK_DOZE_DELAY是一种特殊状态,当设备处于低电量时会进入,因此正常情况LOCATING会切换到IDLE的,只是代码会执行到QUICK_DOZE_DELAY的。
1.3 Deep Idle 状态机状态转换表
状态 (State) | 进入条件 (Entry Conditions) | 触发方法/逻辑 |
STATE_ACTIVE | 屏幕开启 OR 正在充电 OR 即将触发闹钟 OR 有紧急呼叫活跃。 | 初始状态,通过 becomeActiveLocked() 激活。 |
STATE_INACTIVE | 屏幕关闭 AND 未充电 AND 无紧急呼叫。 | becomeInactiveIfAppropriateLocked()(且未启用 Quick Doze)。 |
STATE_QUICK_DOZE_DELAY | 同 STATE_INACTIVE,且关闭了位置、运动检测和显著运动监控。 | becomeInactiveIfAppropriateLocked()(且启用 Quick Doze)。 |
STATE_IDLE_PENDING | 开启显著运动监控(等待检测运动)。 | 从 STATE_INACTIVE 通过 stepIdleStateLocked() 进入。 |
STATE_SENSING | 监控任意运动(包括显著运动和普通运动)。 | 从 STATE_IDLE_PENDING 通过 stepIdleStateLocked() 进入。 |
STATE_LOCATING | 正在请求位置信息,且运动监控仍开启。 | 从 STATE_SENSING 通过 stepIdleStateLocked() 进入。 |
STATE_IDLE | 关闭位置和运动检测,保持显著运动监控状态不变。 | 从 STATE_SENSING(无位置服务)或 STATE_LOCATING/STATE_QUICK_DOZE_DELAY 通过 stepIdleStateLocked() 进入。 |
STATE_IDLE_MAINTENANCE | 空闲维护窗口(短暂唤醒以执行任务)。 | 从 STATE_IDLE 通过 stepIdleStateLocked() 进入。 |
2.DeepIde 省电管控措施
进入deep idle需要1小时4.5mins,deep idle周期时间为1小时、2小时、4小时、最大6小时,维护窗口时间为5mins。窗口期的意思就是每1,2,4,6小时的间隔留5分钟放风期,让被限制的应用有机会临时解除限制,进行后台活动,例如消息推送接收或数据同步。这里也体现出批量放风的功耗管控思维。
在休眠Idle期间,设备会受到以下限制:
1.应用无法访问网络。
2.应用唤醒锁定被忽略。
3.闹钟被延迟。闹钟响铃以及使用
setAndAllowWhileIdle() 设置的闹钟(当设备处于低电耗模式时,限于每个应用每 15 分钟 1 次)除外。此豁免规则适用于必须显示活动提醒通知的应用(如日历)。
4.无法执行 WLAN 扫描。
5.SyncAdapter 同步和
JobScheduler 作业被延迟,直到下一个维护时段才能恢复。
6.接收短信和彩信的应用被暂时列入白名单,以便它们可以完成处理任务。
3.退出DeepIde的机制
当平台检测到以下任意情况时,会使设备退出低电耗模式,从这里我们可以看出Doze模式进入是严进宽出的模式
1.用户与设备互动
2.设备移动操作
3.设备屏幕打开
4.AlarmClock 即将响铃
备注:消息通知不会使设备退出低电耗模式。
4.Doze白名单分类
什么时候配置白名单呢?一般是应用因被doze管控,导致一些消息接收不及时,需要根据是否第三方应用或系统内置应用进行不同路径的配置文件进行配置。
变量名 | 加载方式 | 作用范围 | 调用场景 | 组成/备注 |
用户应用白名单 | ||||
mPowerSaveWhitelistUserApps | onStart中通过config文件加载 | 省电模式下所有用户应用 | 直接调用 | 基础用户白名单列表 |
mPowerSaveWhitelistUserAppIds | 由mPowerSaveWhitelistUserApps生成 | 同mPowerSaveWhitelistUserApps | 仅用于dump打印 | 用户白名单的ID形式(如UID) |
mPowerSaveWhitelistUserAppIdArray | 同mPowerSaveWhitelistUserAppIds | 同mPowerSaveWhitelistUserApps | 提供Binder远程调用 | 用户白名单ID数组,供AMS/PMS访问 |
系统应用白名单 | ||||
mPowerSaveWhitelistSystemAppIds | onStart中通过config文件加载 | 所有省电模式下的系统应用 | 直接调用 | 基础系统白名单(含IDLE场景) |
mPowerSaveWhitelistSystemAppIdsExceptIdle | onStart中通过配置文件加载 | 省电模式但排除IDLE状态的系统应用 | Binder远程增删 | 系统白名单的子集(IDLE状态不生效) |
混合白名单 | ||||
mPowerSaveWhitelistAllAppIds | 由以下两者组成: | 所有省电模式下的全部应用(系统+用户) | 仅用于dump打印 | mPowerSaveWhitelistApps + mPowerSaveWhitelistUserApps |
mPowerSaveWhitelistAllAppIdArray | 同mPowerSaveWhitelistAllAppIds | 同mPowerSaveWhitelistAllAppIds | 向AMS/PMS设置全局白名单 | 全局白名单的数组形式,供系统服务调用 |
排除IDLE的白名单 | ||||
mPowerSaveWhitelistExceptIdleAppIds | 由以下两者组成: | 省电模式但排除IDLE状态的全部应用 | 无直接调用(仅逻辑组合) | mPowerSaveWhitelistAppsExceptIdle + mPowerSaveWhitelistUserApps |
mPowerSaveWhitelistExceptIdleAppIdArray | 同mPowerSaveWhitelistExceptIdleAppIds | 同mPowerSaveWhitelistExceptIdleAppIds | Binder远程调用 | 排除IDLE的白名单数组,功能与mPowerSaveWhitelistExceptIdleAppIds一致 |
Android手机的Settings也提供了Doze白名单的手动设置入口:
如果不配置白名单,新安装的应用默认是归为doze的自动管控规则,即优化选项