概述
Doze模式,官方翻译为低电耗模式,是Andoriod6.0增加的一项系统服务,主要目的是为了优化电池性能,增加电池续航时间,Doze模式又分两种模式:深度Doze模式(Deep Doze)和轻度Doze模式(Light Doze),如果用户长时间没有主动使用其设备,处于静止状态且屏幕已关闭,则系统会使设备进入Doze模式,也就是深度Doze模式。如果用户关闭设备屏幕但仍处于移动状态时,则设备进入轻度Doze模式,此外,轻度Doze模式只适合Android7.0及以上版本。
当用户长时间未使用设备时,设备进入Doze模式,Doze模式会延迟应用后台 CPU 和网络活动,从而延长电池续航时间。处于Doze模式的设备会定期进入维护时段,在此期间,应用可以完成待进行的活动。然后,Doze模式会使设备重新进入较长时间的休眠状态,接着进入下一个维护时段。在达到几个小时的休眠时间上限之前,平台会周而复始地重复Doze模式休眠/维护的序列,且每一次都会延长Doze模式时长。处于Doze模式的设备始终可以感知到动作,且会在检测到动作时立即退出Doze模式。整个Doze图示如下:

Deep Doze 和Light Doze模式对比如下:
| 操作 | 低电耗模式 | 轻度低电耗模式 |
|---|---|---|
| 触发因素 | 屏幕关闭、电池供电、静止 | 屏幕关闭、电池供电(未插电) |
| 时间 | 随维护时段依次增加 | 随维护时段反复持续 N 分钟 |
| 限制 | 无法进行网络访问、唤醒锁忽略、 GPS/WLAN无法扫描、闹钟和SyncAdapter/JobScheduler被延迟。 | 无法进行网络访问、SyncAdapter/JobScheduler |
| 行为 | 仅接收优先级较高的推送通知消息。 | 接收所有实时消息(即时消息、来电等)。优先级较高的推送通知消息可以暂时访问网络。 |
| 退出 | 设备有移动、和用户有交互、屏幕开启、闹钟响铃 | 屏幕开启。 |
接下来就分析Doze的实现原理。Doze模式是通过DeviceIdleController来实现的。
1.DeviceIdleController的启动流程
DeviceIdleController(以下简称DIC)继承于SystemService,因此也是一个系统服务,在分析PMS的时候说过,继承于SytemService的服务启动有以下几个共同点:
- 1.在SystemServer中实例化并启动,启动时会执行SytemService的生命周期方法:
Constructor()->onStart()->onBootPhase(); - 2.内部维护一个Binder和其他服务进行IPC通讯;
- 3.内部维护一个Internal类用于和System进程进行交互;
下面就从SystemServer开始分析DIC的启动流程。
在SystemServer启动其他服务时启动DIC:
private void startOtherServices() {
.............
mSystemServiceManager.startService(DeviceIdleController.class);
............
}
在SystemServiceManager中,通过反射的方式获取了DIC对象,并且调用了onStart()方法:
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
....................
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
final T service;
try {
//通过反射获取实例
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
}
//调用同名重载方法
startService(service);
return service;
}
....................
}
public void startService(@NonNull final SystemService service) {
// 加入到mServices列表中
mServices.add(service);
long time = SystemClock.elapsedRealtime();
try {
//调用onStart()开始服务
service.onStart();
} catch (RuntimeException ex) {
}
}
执行到这里,DIC的启动就开始了,再来看看最后一个生命周期方法onBootPhase()的调用,这个方法表示启动服务的过程,在SystemServer中会调用多次,从而在不同的启动阶段完成不同的工作,代码如下:
private void startOtherServices() {
.............
mSystemServiceManager.startBootPhase(SystemService.
PHASE_LOCK_SETTINGS_READY);
.............
mSystemServiceManager.startBootPhase(SystemService.
PHASE_SYSTEM_SERVICES_READY);
.............
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
.............
mSystemServiceManager.

本文详细介绍了Android 6.0引入的Doze模式,旨在优化电池性能和延长续航时间。Doze模式分为深度和轻度两种,设备在静止且屏幕关闭时进入深度Doze,屏幕关闭但移动时进入轻度Doze。Doze模式通过DeviceIdleController(DIC)实现,DIC是SystemService的子类。文章剖析了DIC的启动流程,包括在SystemServer中实例化、Binder通信、生命周期方法的调用,以及如何管理白名单应用。最后,文章提到了DIC如何根据交互状态和网络变化调整Doze模式,并预告了后续对Doze模式实现流程的分析。

1万+

被折叠的 条评论
为什么被折叠?



