Android M新特性Doze and App Standby模式详解

参考:

Optimizing for Doze and App Standby

Android M新特性Doze and App Standby模式详解

深入android6.0 设备 idle状态

Android M 的 Doze 模式下第三方推送服务还能用吗?

一、Optimizing for Doze and App Standby

  1. 从Android6.0开始,Android提供了两种省电延长电池寿命的功能:Doze和App Standby;
  2. 表现形式:当设备没有连接到电源,设备进入Doze模式时,系统将通过延迟最近用户没有使用的应用程序的后台CPU运作及网络活动,让应用程序处于App Standby状态,以此来减少电池消耗。谷歌表示,在Nexus5和Nexus6上测试,当屏幕处于关闭状态,平均续航时间提高30%;
  3. 版本要求:Android6.0(API level 23)及其更高版本;
  4. 开发者影响:为了保证用户的最佳体验,开发者有必要在Doze和App Standby模式下测试应用程序,及其对代码进行相应的调整。

二、Understanding Doze

1.设备进入Doze睡眠模式时机:

  • 用户不操作设备一段时间
  • 屏幕关闭
  • 设备未连接电源充电

2.Doze模式下应用程序有什么变化:

  • 系统试图通过限制应用程序访问网络和CPU密集型服务节省电池;
  • 防止应用程序访问网络,推延应用程序的工作,同步,和标准的警报;
  • 系统定期提供一个短暂的时间让应用程序完成延迟的工作活动,之后再次进入Doze模式。在这个时间片里,系统将提供维持性窗口(maintenance window)应用程序可以在此时执行访问网络,同步,和报警等活动。

Doze模式的五种状态,分别如下:

  1. ACTIVE:手机设备处于激活活动状态
  2. INACTIVE:屏幕关闭进入非活动状态
  3. IDLE_PENDING:每隔30分钟让App进入等待空闲预备状态
  4. IDLE:空闲状态
  5. IDLE_MAINTENANCE:处理挂起任务

如下图所示,Doze期间提供间隔一小段时间(30s)供应用程序使用网络和处理挂起的活动。

从这张图我们可以看到,系统进入Doze模式后,系统会隔一段时间处理正在挂起的任务,随着时间推移,后面间隔的时间会越来越长,以此来减少电量消耗。

3.退出Doze模式:

  • 移动设备
  • 打开屏幕
  • 设备连接电源

以上三种情况会退出Doze模式,之后apps回复正常模式。

4.Doze有哪些限制?

  • 网络连接会被禁止
  • Wake Lock会被屏蔽
  • AlarmManager定时任务延迟到下一个maintenance window进行处理,除非使用AlarmManager提供的方法:setAndAllowWhileIdle() 或者setExactAndAllowWhileIdle()
  • 系统将不扫描热点WIFI
  • 同步工作将被禁止
  • 不允许JobScheduler进行任务调度

5.适配Doze模式有什么方法?

  • Doze影响到AlarmManager闹钟和定时器管理活动,在Android6.0引入了两个新方法:setAndAllowWhileIdle() 和setExactAndAllowWhileIdle(),调用两个方法可以在Doze模式下让系统响应定时任务。
  • Doze模式下限制了网络的连接,如果应用程序依赖于实时信息,那么这个将影响App的体验。那么你需要使用Google Cloud Messaging (GCM)谷歌云消息(后面详细讲解)

三、Understanding App Standby

当用户不触摸使用应用程序一段时间时,该应用程序处于App Standby状态,系统将把该App标志为空闲状态(idle)。除非触发以下任意条件,应用程序将退出App Standby状态:

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

四、Doze和App Standby的区别:

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

五、DeviceIdleController

DeviceIdleController是Doze模式的主要驱动。接下来,我将使用device idle mode而不是doze mode来描述“Doze”,因为它更符合代码的实际情况。

5.1、deviceidle——新的系统服务

如果你已经阅读了官方文档,你可能已经注意到下面的命令,开发者可以通过这些命令得知当下设备的应用行为:

adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step  

对于上面的命令你可能并不熟悉,dumpsys是用来与系统服务交互的(查看它们的状态)。deviceidle是我们之前没有看到过的,它是一个新的系统服务。用来检测是否进入idle mode(Doze模式)

$ adb shell service list | grep deviceidle
59  deviceidle: [android.os.IDeviceIdleController]  

我们可以使用‘-h’看到所有的deviceidle的所有选项:

$ adb shell dumpsys deviceidle -h
Device idle controller (deviceidle) dump options:
  [-h] [CMD]
  -h: print this help text.
Commands:
  step
    Immediately step to next state, without waiting for alarm.
  disable
    Completely disable device idle mode.
  enable
    Re-enable device idle mode after it had previously been disabled.
  whitelist
    Add (prefix with +) or remove (prefix with -) packages. 

5.2、DeviceIdleController的五种状态

DeviceIdleController维持着设备包含的五种状态,和上面介绍的Doze的五种状态是一样的:

  • ACTIVE – 设备在使用中,或者连接着电源。
  • INACTIVE – 设备已经从ACTIVE状态中出来一段时间了(使用者关闭了屏幕或者拔掉了电源)
  • IDLE_PENDING – 请留意,我们将进入idle mode.
  • IDLE – 设备进入idle mode.
  • IDLE_MAINTENANCE – 应用窗口已经打开去做处理.

1、当设备被唤醒和正在使用中,控制器就处于ACTIVE状态,

2、不活跃时间超时,用户关闭屏幕等等,将会使设备状态进入到INACTIVE.

3、INACTIVE状态下,DeviceIdleController将会通过AlarmManager来设置他自己的alarm来驱动进程:

一个alarm会被设置在一个预设的时刻(这个时间在M的预览中是30分钟)。

当这个alarm生效后,DeviceIdleController 会进入到IDLE_PENDING然后再次设置同样的alarm。

4、当触发下一个alarm后,控制器会进入到IDLE 状态,进入到这个状态后,应用特性会被完全限制。

5、IDLE 状态后,会在IDLE 和IDLE_MAINTENANCE两个状态之间周期性的跳转。IDLE_MAINTENANCE也就是Doze中提到的maintenance window,在这个状态下,应用程序可以在此时执行访问网络,同步,和报警等活动。

这些服务的公共API(由IDeviceIdleController 接口展现)持有全部方法访问白名单。应用(系统应用或其它第三方应用)任何情况下都不能驱动控制器状态

5.3、DeviceIdleController 维护着一个应用白名单

正如你在上面的帮助菜单中看到的一样,DeviceIdleController 维护着一个应用白名单,不需要额外的参数,通过dump服务的状态,我们能够看到现在的这个列表:

$ adb shell dumpsys deviceidle
  Whitelist system apps:
    com.android.providers.downloads
    com.android.vending
    com.google.android.gms
  Whitelist app uids:
    UID=10012: true
    UID=10016: true
    UID=10026: true
  …  

这个名单分为两个部分:系统应用和第三方应用。

系统应用

系统应用会被平台制作者通过配置定义列在白名单中。下面这个是从Nexus 6中得到的一个配置定义例子,它将GMS核心(在GCM中使用),应用商店,以及一个任意的用于电源监控的app白名单化:

<?xml version="1.0" encoding="utf-8"?>
<!-- These are configurations that must exist on all GMS devices. -->
<config>
    <allow-in-power-save package="com.google.android.gms" />  

    <allow-in-power-save package="com.android.vending" />  

    <allow-in-power-save package="com.google.android.volta" />
</config> 

其它的系统服务可以通过SystemConfig的实例访问到这些值。DeviceIdleController使用SystemConfig.getAllowInPowerSave()将这些系统定义的元素放到白名单中。

注意:当设备处于“省电模式”时,同样也是这个配置文件决定哪个系统应用可以在后台开启服务。

第三方应用

白名单中剩下的部分是用户定义的,这些项可以通过两种方式被增加和删除。

第一种:开发者可以通过dumpsys接口使用白名单命令:

$ adb shell dumpsys deviceidle whitelist +com.example.myapplication
$ adb shell dumpsys deviceidle
  Whitelist system apps:
    com.android.providers.downloads
    com.android.vending
    com.google.android.gms
  Whitelist user apps:
    com.example.myapplication
  Whitelist app uids:
    UID=10012: true  

第二种:用户可以通过设置(Settings -> Battery -> Ignore optimizations)来修改白名单。

另外:在小米手机中,神隐模式中把应用设置为无限制或者在近期任务中下拉锁定,就会出现在上述的白名单中。

六、测试Doze和App Standby模式的方法(Adb命令)

测试Doze模式

1、 首先确保你的硬件或虚拟设备是Android6.0或更高版本系统;

2、 连接设备到开发机上并安装你的app;

3、 运行app并让其运行活动;

4、 关闭设备的屏幕;

5、运行以下adb命令使系统进入Doze模式:

$ adb shell dumpsys battery unplug

$ adb shell dumpsys deviceidle step

你可能需要多次执行第二条命令,直到设备处于idle 状态。注意,第一条命令的意思是,拔去电源,即使现在正在插着usb调试,也不会充电。建议运行$ adb shell dumpsys battery reset,否则会出现手机充不上电的情况。

6、 观察你的app表现行为是否有需优化改进的地方。

测试App Standby模式

步骤1-3同测试Doze模式

4、 运行以下adb命令迫使系统进入App Standby模式:

$ adb shell dumpsys battery unplug

$ adb shell am set-inactive <packageName> true

5、 模拟唤醒你的应用程序使用以下命令:

$ adb shell am set-inactive <packageName> false

$ adb shell am get-inactive <packageName>

6、 观察你的App,确保应用程序可以从standby mode优雅得恢复,应该检查App的通知及后台能按预期的继续工作。

七、客户端使用方法:

  1. App程序可发送action为ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS的intent引导用户进入设置界面将应用程序设置进白名单列表里。
  2. 应用程序还可以使用AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限来触发一个系统对话来让用户添加到白名单里,而无需进入设置界面去设置。

当然,官方也提供用户把你的App移除电池优化白名单的选项。这个白名单也会被Android M的另一个新特性 App Standby使用,所以用户只能简单的进行控制,也就是说设备并不会完全相信这个白名单。

这个白名单只是谷歌的一个建议,就是说在下面这些情况下,你可以使用上面两张方法,来引导用户把你的app设为白名单

官方举了一下白名单例子:

总结:

我认为Doze 模式和 APP Standby模式,限制app的权限种类都是一样的。都是进入idle状态。只是各自模式的进入和退出所需要的条件不一样、进入模式后控制APP的周期也不一样。

Doze模式的推出本身是为了减少电池的消耗,且Google希望统一使用GCM来传递消息进行通讯,而对于国内开发来讲,确实带来了很大的麻烦:

  1. 国内开发的一些消息推送机制(PUSH)将受到影响;
  2. 若使用GCM,在国内使用GCM延迟高,对于即时通讯产品来说选择还需勇气啊;
  3. 国内第三方手机厂商如华为、小米、三星,定制的Rom也将使用定制的推送消息机制。这让同一款App如何选择哪种推送机制才能兼容呢?

解决方法:

  1. 用户添加应用程序到电池优化白名单列表;
  2. 开发者使用Google提供的ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS意图和AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限设置以此忽略(推荐);
  3. 使用Google提供的GCM;
  4. 通过so绕过Doze模式。


我使用MIUI 7.5(Android 6.0.1)测试过程中发现,自己维持长连接一进入standby模式,网络就断了(手机其它app网络正常),但是运行在后台的代码还是一直在跑,log也能正常输出到手机的文件上,就是连不上网。按照官方的描述进入standby模式,工作应该被挂起,但是为什么后台代码还是正常运行呢??请高人指点一下

  • 微信的主进程可以手动设置为standby 模式,
  • APP的子进程都是无法设置为standby 模式,但是如果主进程是standby 模式,子进程也会是standby 模式。即使使用命令查看子进程的standby 状态也是false。
  • 在正常使用手机的情况下,微信的主进程无法进入standby 模式,感觉是使用so绕过standby模式。具体so文件是怎么实现的,还请大神指点一下。
时间: 2024-10-12 23:51:29

Android M新特性Doze and App Standby模式详解的相关文章

ES6新特性三: Generator(生成器)函数详解

本文实例讲述了ES6新特性三: Generator(生成器)函数.分享给大家供大家参考,具体如下: 1. 简介 ① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改变. ② 写法: function* f() {} ③ 作用:就是可以完全控制函数的内部状态的变化,依次遍历这些状态. ④ 运行过程:当调用Generator函数的时候,该函数并不执行,而是返回一个遍历器(可以理解成暂停执行).通过调用next()开始执行,遇到yield停止执行,返回一个value

Java8新特性Stream API与Lambda表达式详解(1)

1 为什么需要Stream与Lambda表达式? 1.1  为什么需要Stream Stream作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream.Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggr

Android N 新特性

2016年5月19日,谷歌在美国加州的山景城举办了 Google I/O 开发者大会中发布.2016年6月,Android N正式命名为"牛轧糖" 本届I/O开发者大会上,Google重点介绍了Android系统三个维度:分别是性能.安全和生产力.其中性能主要新增了Vulkan API与JIT编译器(前者优化图形性能.或者加快软件安装速度):安全性包括新的数据加密方式.恶意网站识别.系统的实时更新:生产力方面加入了分屏多任务功能.程序的快速切换,所有应用都可以支持"多窗口模式

Android Lollipop 新特性 - Palette;获取图片颜色

Android Lollipop 新特性 - Palette 在Android 5.0 之后推出的palette,通过这个方法,我们就可以从一张 bitmap 中提取我们需要的颜色,可以使UI风格更加美观融洽.比如,我们可以从图片中提取颜色设置给ActionBar做背景颜色,这样ActionBar的颜色就会随着显示图片的变化而变化. Palette可以提取的颜色如下: Vibrant (有活力的) Vibrant dark(有活力的 暗色) Vibrant light(有活力的 亮色) Mute

Android基础入门教程——2.3.2 EditText(输入框)详解

Android基础入门教程--2.3.2 EditText(输入框)详解 标签(空格分隔): Android基础入门教程 本节引言: 上一节中我们学习了第一个 UI控件TextView(文本框),文中给出了很多实际开发中可能遇到的一些需求 的解决方法,应该会为你的开发带来便利,在本节中,我们来学习第二个很常用的控件EditText(输入框): 和TextView非常类似,最大的区别是:EditText可以接受用户输入!和前面一样,我们不一个个讲属性, 只讲实际应用,要扣属性可以自己查看API文档

Android异步处理三:Handler+Looper+MessageQueue深入详解

Android Loop&Handle学习总结 - New Start - 博客频道 - CSDN.NET ?????? 昨晚偷懒,这篇博客只写了一个标题,今天早晨一看,还有15的阅读量.实在是对不起那些同学.......换了是我,也会BS这样的LZ吧!sorry 啦 -------------------------------------------------------------------------------------------------------------------

Android中launchMode模式详解

关于Android中launchMode的文章介绍的真心不少,广为流传而且介绍的最详细的莫过于这篇文章http://blog.csdn.net/android_tutor/article/details/6310015.但是这篇文章中关于singletask和singleinstance在评论中还是有些不解和争论,在此根据实例重点说下这两种模式: 实例简介:有两个Activity,分别为AActivity和BActivity,界面相同.点击按钮A和B,分别启动AActivity和BActivit

Android基础入门教程——8.3.16 Canvas API详解(Part 1)

Android基础入门教程--8.3.16 Canvas API详解(Part 1) 标签(空格分隔): Android基础入门教程 本节引言: 前面我们花了13小节详细地讲解了Android中Paint类大部分常用的API,本节开始我们来讲解 Canvas(画板)的一些常用API,我们在Android基础入门教程--8.3.1 三个绘图工具类详解 中已经列出了我们可供调用的一些方法,我们分下类: drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前

【Android语音合成TTS】云知声离线TTS使用详解

请尊重他人的劳动成果,转载请注明出处:[Android语音合成TTS]云知声离线TTS使用详解 PS. 云知声是2012年创立的,虽然只有1年多的发展历程,但其语音识别技术核心团队已经从业十余年,积累颇丰,这也是为什么能够短短一年时间能够在语音识别领域内做得风生水起的缘故.微语音插件.搜狗语音助手.乐视超级电视.老罗锤子操作系统.触宝输入法,还有网易+电信推出的的易信,用的是云知声的语音识别.2013年,云知声在资本市场的认可度非常高,极受追捧. 目前云知声提供免费的离线TTS,但API比较少,