版权声明:本文由郑桂涛原创文章,转载请注明出处:
文章原文连接:https://www.qcloud.com/community/article/185shell
来源:腾云阁 https://www.qcloud.com/community后端
从Android6.0开始,Android提供了两种省电延长电池寿命的功能:Doze和App Standby;服务器
表现形式:当设备没有链接到电源,设备进入Doze模式时,系统将经过延迟最近用户没有使用的应用程序的后台CPU运做及网络活动,让应用程序处于App Standby状态,以此来减小电池消耗。谷歌表示,在Nexus5和Nexus6上测试,当屏幕处于关闭状态,平均续航时间提升30%;网络
版本要求:Android6.0(API level 23)及其更高版本;app
开发者影响:为了保证用户的最佳体验,开发者有必要在Doze和App Standby模式下测试应用程序,及其对代码进行相应的调整。测试
用户不操做设备一段时间优化
屏幕关闭spa
设备未链接电源充电server
系统试图经过限制应用程序访问网络和CPU密集型服务节省电池;生命周期
防止应用程序访问网络,推延应用程序的工做,同步,和标准的警报;
系统按期提供一个短暂的时间让应用程序完成延迟的工做活动,在这个时间片里,系统将提供维持性窗口应用程序访问网络,运行在等待的同步,工做,和报警等活动。
Doze模式的五种状态,分别以下:
ACTIVE:手机设备处于激活活动状态
INACTIVE:屏幕关闭进入非活动状态
IDLE_PENDING:每隔30分钟让App进入等待空闲预备状态
IDLE:空闲状态
IDLE_MAINTENANCE:处理挂起任务
以下图所示,Doze期间提供间隔一小段时间(30s)供应用程序使用网络和处理挂起的活动。
从这张图咱们能够看到,系统进入Doze模式后,系统会隔一段时间处理正在挂起的任务,随着时间推移,后面间隔的时间会愈来愈长,以此来减小电量消耗。
用户唤醒装置移动,打开屏幕
或者设备链接电源
网络链接会被禁止
Wake Lock会被屏蔽
AlarmManager定时任务延迟到下一个maintenance window进行处理,除非使用AlarmManager提供的方法:setAndAllowWhileIdle() 或者setExactAndAllowWhileIdle()
系统将不扫描热点WIFI
同步工做将被禁止
不容许JobScheduler进行任务调度
Doze影响到AlarmManager闹钟和定时器管理活动,在Android6.0引入了两个新方法:setAndAllowWhileIdle() 和setExactAndAllowWhileIdle(),调用两个方法能够在Doze模式下让系统响应定时任务
Doze模式下限制了网络的链接,若是应用程序依赖于实时信息,那么这个将影响App的体验。那么你须要使用Google Cloud Messaging (GCM)谷歌云消息(后面详细讲解)
测试Doze模式
首先确保你的硬件或虚拟设备是Android6.0或更高版本系统;
链接设备到开发机上并安装你的app;
运行app并让其运行活动;
关闭设备的屏幕;
运行如下adb命令使系统进入Doze模式:
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
观察你的app表现行为是否有需优化改进的地方。
测试App Standby模式
步骤1-3同测试Doze模式
运行如下adb命令迫使系统进入App Standby模式:
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive true
模拟唤醒你的应用程序使用如下命令:
$ adb shell am set-inactive false
$ adb shell am get-inactive
观察你的App,确保应用程序恢复正常从待机模式过程当中,App的通知及其背部活动能达到预期结果。
当用户不触摸使用应用程序一段时间时,该应用程序处于App Standby状态,系统将把该App标志为空闲状态。除非触发如下任意条件,应用程序将退出App Standby状态:
用户主动启动该App;
该App当前有一个前台进程(或包含一个活动的前台服务,或被另外一个activity或前台service使用);
App生成一个用户所能在锁屏或通知托盘看到的Notification, 而当用户设备插入电源时,系统将会释放App的待机状态,容许他们自由的链接网络及其执行未完成的工做和同步。若是设备空闲很长一段时间,系统将容许空闲App一天一次访问网络。
Doze模式须要屏幕关闭(一般晚上睡觉或长时间屏幕关闭才会进入),而App Standby不须要屏幕关闭,App进入后台一段时间也会受到链接网络等限制。
Google Cloud Messaging(GCM)是一个云到设备的服务,可让你支持实时在云端服务和Android设备上应用程序之间的消息传递。
GCM提供了一个持久链接到云端的连接,让全部须要实时消息传递应用程序能够共享此连接。这个共享连接显著优化电池消耗,使其没必要让多个应用程序各位维护本身单独的持久连接而使电池迅速耗尽。
因为这个缘由,官方建议:若是你的应用须要消息传递与后端服务集成,咱们强烈建议尽量的使用GCM,而不是单独维护本身的网络连接。
GCM消息拥有高优先级,不影响Doze模式,且不会不影响其余应用程序的状态。这意味着你的应用程序可使用它们进行通讯,同时最大限度地减小电池在整个系统和设备的影响。
如下来GCM自官方解释:
一个GCM实现包括谷歌链接服务器,在你的环境中经过HTTP或XMPP协议的链接服务器进行交互的应用程序服务器和客户端应用程序。
生命周期流程:
注册启用GCM: 客户端应用程序注册为接收消息。
发送和接收下行消息:
发送一个消息,该应用程序服务器发送信息到客户端应用程序:
1.该应用程序服务器发送消息给GCM链接服务器;
2.当设备处于脱机状态,该GCM链接服务器入队并存储消息;
3.当设备联机时,GCM链接服务器将邮件发送到该设备;
4.在设备上,所述客户端应用程序根据该特定平台实现接收该消息。
接收消息,客户端应用程序收到一条消息从GCM链接服务器。
发送和接收上游的消息: 若是您使用的是此功能只提供XMPP链接服务器 。
发送一个消息,客户端应用程序将消息发送到应用服务器:
1.在设备上,客户端应用程序将消息发送到XMPP链接server;
2.若是该服务器已断开链接,该XMPP服务器链接入队并存储信息;
3.当应用程序服务器从新链接后,XMPP链接服务器将邮件发送到应用程序服务器。
接收消息,一个应用服务器从XMPP链接服务器接收邮件,而后执行如下操做:
一、解析消息头,以验证客户端应用程序发送的信息;
二、发送“确认”的XMPP链接服务器以确认收到该消息;
三、任选解析该消息有效载荷,由客户端应用程序所定义的。
除了GCM,Android6.0及更高版本还提供了Doze模式白名单列表,经过设置应用程序进入白名单列表可逃脱Doze模式的各类限制。
检测应用程序是否存在白名单list里面,可以使用PowerManager的isIgnoringBatteryOptimizations()方法。
用户也可手动设置应用程序进入白名单列表里面,路径为:设置>电池>电池优化白名单:
客户端使用方法:
App程序可发送action为ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS的intent引导用户进入设置界面将应用程序设置进白名单列表里。
应用程序还可使用AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限来触发一个系统对话来让用户添加到白名单里,而无需进入设置界面去设置。
固然,官方也提供用户把你的App移除电池优化白名单的选项。这个白名单也会被Android M的另外一个新特性 App Standby使用,因此用户只能简单的进行控制,也就是说设备并不会彻底相信这个白名单。
官方举了一下白名单例子:
$ adb shell dumpsys deviceidle whitelist +
$ adb shell dumpsys deviceidle
Doze模式的推出自己是为了减小电池的消耗,且Google但愿统一使用GCM来传递消息进行通信,而对于国内开发来说,确实带来了很大的麻烦:
国内开发的一些消息推送机制(PUSH)将受到影响;
若使用GCM,在国内使用GCM延迟高,对于即时通信产品来讲选择还需勇气啊;
国内第三方手机厂商如华为、小米、三星,定制的Rom也将使用定制的推送消息机制。这让同一款App如何选择哪一种推送机制才能兼容呢?
用户添加应用程序到电池优化白名单列表;
开发者使用Google提供的ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS意图和AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限设置以此忽略(推荐);
使用Google提供的GCM;
经过so绕过Doze模式。