Doze and app standby介绍

1 简介

从android 6.0(API 23) 开始,android为了延长电池的使用时间,引入了两个新的省电特性.当手机没有进行充电时,通过管理app的行为到达省电目的. 当设备较长时间没有使用的时候,设备会进入Doze模式,此时,屏幕是灭屏的,app的cpu和网络的使用将会延时处理.app standby是将app没有处于前台, 该app的网络使用将会被限制,此时不需要灭屏.
Doze and app standby 需要 API 23以及更高的版本.

2 理解Doze

在设备不充电,灭屏,较长一段时间用户没有使用移动设备的情况下,设备会进入Doze模式.在Doze模式下,系统会限制APP的网络和cup服务来达到省电的目的. 并且Doze模式还会延迟app的jobs, syncs, and standard alarms. 系统会定期退出一段时间让被阻止的APP去完成自己被延时的工作,这个时间片段被叫做maintenance window.在maintenance window期间所有app都可以去完成 被挂起的jobs, syncs, and standard alarms以及允许APP连接网络. Doze 当一个maintenance window结束之后,设备又会进入Doze模式.挂起网络,延迟APP的jobs, syncs, and standard alarms.不同的是maintenance window之间的 间隔会越来越长.这样的策略是为了省电.

2.1 Doze模式的限制

处于Doze模式,APP会有以下限制

  • 网络访问被暂停
  • 系统会忽略wack lock
  • 标准的alarm(setExact() 和 setWindow())会被推迟到下一个maintenance window去执行
    如果在设备处于Doze下,需要使用alarm去唤醒,需要使用setAndAllowWhileIdle() / setExactAndAllowWhileIdle().
  • 系统不再进行wifi扫描
  • 系统不允许执行 sync adapters
  • 系统不允许执行 JobScheduler(也就是限制了jobs)

2.2 Doze的状态以及变化

Doze的状态的变化是Doze的核心设计,下面介绍Doze的进入,状态变化,退出

2.2.1 Doze状态的进入

Android M 满足以下条件,进入Doze:

  • 用户不操作设备一段时间 (通过动作监测来判断)
  • 屏幕关闭
  • 设备未连接电源充电

在Android N中不需要满足设备是否移动,分为浅度doze(light idle)和深度doze(deep idle)

级别 进入条件 对App的行为限制 退出条件 设备硬件要求
第一级别限制 浅度IDLE(Light IDLE) 1不能访问网络;
2推迟作业和同步
激活屏幕,设备充电
第二级别限制 深度IDLE(Deep IDLE) 1 不能访问网络;
2 wake lock失效;
3 禁止GPS/WIFI 扫描;
4 Alarms推迟;
5 作业,同步推迟。
激活屏幕,设备充电,有移动动作,Alarm 到时 要求具有SMD(Significant motion Dector),一种用于检测设备是否处于静止状态传感器

注:Notifications的到来不会导致退出doze模式

2.2.2 Doze的五种状态

Doze的核心就是使用了状态的变化,主要是使用控制机器在五种状态下面切换,下面对五种状态进行说明:

  • ACTIVE:手机设备处于激活活动状
  • INACTIVE:屏幕关闭进入非活动状态
  • IDLE_PENDING:每隔30分钟让App进入等待空闲预备状态
  • IDLE:空闲状态
  • IDLE_MAINTENANCE:处理挂起任务 下图是状态转移的图: doze_state_change:

2.2.3 Doze的退出

退出Doze和进入相对应,只要进入条件的其中一个不满足就会退出Doze,对应如下:

  • 用户唤醒装置移动
  • 打开屏幕
  • 连接电源

2.3 在Doze下适配APP

由于在Doze模式下,APP的jobs, syncs, and standard alarms以及APP连接网络,会被收到限制,但是APP如果是真的要使用,有两种方式:

  • 使用白名单,在白名单有系统白名单,用户添加的白名单,临时白名单(10s);在白名单之中的APP能够在Doze模式下豁免;
  • 使用setAndAllowWhileIdle() / setExactAndAllowWhileIdle(),不过这也是有限制的,每个APP每9分钟只能触发一次,这两个方法的本质是将APP加入临时的白名单, 来达到在Doze模式下,仍然可以使用alarm下唤醒机器.
  • 使用 Firebase Cloud Messaging(FCM),之前是Google Cloud Messaging(GCM),该服务就是google的专用通道,在android中有较高的优先级.APP要执行的操作, FCM

在设备Doze模式下的设备,APP只要将要唤醒,更新等操作,从服务器发送到FCM是,由FCM统一发送即可,避免了每个 APP都与设备建立一个长链接用于推送信息.并且FCM在android拥有高的优先级,能够在Doze模式下,不影响其他APP的前提下,唤醒APP,达到省电目的.

2 理解APP standby

2.1 APP standby策略

当用户不触摸使用APP,一段时间后,系统会判定进入APP进入空闲状态.当包含以下任意一种情况,App就会退出App Standby状态:

  • 用户主动启动App;
  • App有一个前台进程,或包含一个前台服务,或被另一个activity或前台service使用;
  • App生成一个用户所能在锁屏或通知托盘看到的Notification,而当用户设备插入电源时,系统将会释放App的待机状态,允许他们自由的连接网络及其执行未完成的工作和同步。如果设备空闲很长一段时间,系统将允许空闲App一天一次访问网络。

2.2 Doze和App Standby的区别

Doze模式需要屏幕关闭(通常晚上睡觉或长时间屏幕关闭才会进入),而App Standby不需要屏幕关闭,App进入后台一段时间也会受到连接网络等限制。

3 低电耗模式测试app

App要去测试,适配Doze,App Standby,避免一些功能不能使用.

3.1 测试Doze模式

  • 使用 Android 6.0(API 级别 23)或更高版本的系统映像配置硬件设备或虚拟设备
  • 将设备连接到开发计算机并安装应用
  • 运行应用并使其保持活动状态
  • 关闭设备屏幕。(应用保持活动状态。)
  • 通过运行以下命令强制系统在低电耗模式之间循环切换:

    1. $ adb shell dumpsys battery unplug
    2. $ adb shell dumpsys deviceidle step

    可能需要多次运行第二个命令。不断地重复,直到设备变为空闲状态。

  • 在重新激活设备后观察应用的行为.确保应用在设备退出低电耗模式时正常恢复.

3.2 测试App Standby模式

  • 使用 Android 6.0(API 级别 23)或更高版本的系统映像配置硬件设备或虚拟设备
  • 将设备连接到开发计算机并安装应用
  • 运行应用并使其保持活动状态
  • 通过运行以下命令强制应用进入应用待机模式:
    1. $ adb shell am set-inactive <packageName> false
    2. $ adb shell am get-inactive <packageName>
  • 观察唤醒后的应用行为。确保应用从待机模式中正常恢复。 特别地,您应检查应用的通知和后台作业是否按预期继续运行