转载请标明出处:http://blog.csdn.net/xx326664162/article/details/52312122 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货

一、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文件是怎么实现的,还请大神指点一下。

参考:
Optimizing for Doze and App Standby
Android M新特性Doze and App Standby模式详解
深入android6.0 设备 idle状态
Android M 的 Doze 模式下第三方推送服务还能用吗?

Android M新特性Doze and App Standby模式详解相关推荐

  1. Android  Doze and App Standby模式详解

    Android  Doze and App Standby模式详解 来源:腾云阁 https://www.qcloud.com/community Optimizing for Doze and Ap ...

  2. mysql 双冒号_jdk8新特性之双冒号 :: 用法及详解

    jdk8的新特性有很多,最亮眼的当属函数式编程的语法糖,本文主要讲解下双冒号::的用法. 概念 类名::方法名,相当于对这个方法闭包的引用,类似js中的一个function.比如: Function  ...

  3. Servlet3.0新特性WebFilter(Annotation Filter)详解

    摘要: Servlet3.0作为J2EE 6规范一部分,并随J2EE6一起发布,WeFilter是过滤器注解,是Servlet3.0的新特性,不需要在web.xml进行配置,简化了配置. Name T ...

  4. java双冒号_jdk8新特性之双冒号 :: 用法及详解

    jdk8的新特性有很多,最亮眼的当属函数式编程的语法糖,本文主要讲解下双冒号::的用法. 概念 类名::方法名,相当于对这个方法闭包的引用,类似js中的一个function.比如: Function ...

  5. ES5总结1:数组Array新特性最全最精简的详解

    2个位置方法:indexOf  lastIndexOf 5个迭代方法:forEach       every  some       filter  map 2个高阶函数:reduce  reduce ...

  6. C++11新特性之变长参数模板详解

    本文主要介绍了C++11变长参数模板,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 目录 C++11 变长参数模板 变长函数参数 ...

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

    2019独角兽企业重金招聘Python工程师标准>>> http://blog.csdn.net/caihuangshi/article/details/51298622 转载于:h ...

  8. concat 不是可以识别的 内置函数名称。_新特性解读 | MySQL 8.0 窗口函数详解

    背景 一直以来,MySQL 只有针对聚合函数的汇总类功能,比如MAX, AVG 等,没有从 SQL 层针对聚合类每组展开处理的功能.不过 MySQL 开放了 UDF 接口,可以用 C 来自己写UDF, ...

  9. Android系统(187)---最易懂的Activity启动模式详解

    Android基础:最易懂的Activity启动模式详解 前言 Android基础中,Activity的启动模式非常重要 本文将全面介绍 Activity的启动模式 目录 目录 1. 定义 即Acti ...

最新文章

  1. html脱机不显示图片,Python绘图脱机图表嵌入HTML(不工作)
  2. 多任务版udp聊天器
  3. 为什么梯度的方向与等高线切线方向垂直?
  4. python我的世界给予物品指令_我的世界指令给予物品 我的世界指令给予物品是多少...
  5. linux 基础命令 1
  6. 一款开源且功能强大的C#甘特图控件.NET Winforms Gantt Chart Control
  7. itsdangerous
  8. 虚拟应用DemoApp功能演示详解
  9. java入门编程(菜鸟教程)
  10. GD32E230开发初体验
  11. IDA7.5 无法打开解决方法
  12. cisco下模拟Linux防火墙,Cisco防火墙HA实例
  13. 学习PMBOK对ITTO输入输出的技术工具整理(关系)
  14. java中新建对象设为null 和new 一个对象的区别
  15. No toolchains found in the NDK toolchains folder for ABI with prefix:XXX
  16. 全网目前最全python例子(附源码)八、Python实战
  17. 上知天文,下知地理,还能替人写脚本!人工智能的进阶ChatGPT
  18. 总结2016,展望2017
  19. 一个Java画图板程序的设计
  20. 2019数学建模国赛总结

热门文章

  1. Tomcat启动时报错:-Djava.endorsed.dirs = D:\ Tomcat 8.0 \ endorsed不受支持。
  2. 工时表:如何跟踪团队进度?
  3. Egg Dropping Puzzle
  4. 网络Ghost克隆操作全程实例图解(图)
  5. 网络高可用HA和特性导图
  6. asp.net html代码亚索,asp.net利用RAR实现文件压缩解压缩
  7. js 四句话搞懂原型和原型链
  8. Cocos Creator 打包WebMobile,实现资源代码分离,部署 cdn
  9. html中如何写一个提示框,html弹出公告 html中点击列表文字弹出提示框?
  10. 计算机网络维护工具,一种计算机网络设备维护用的工具箱的制作方法