Android 8.1 Doze模式分析(一)——Doze简介和DeviceIdleController的启动

概述

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);
    .............
    mSystemServiceMana
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值