当我们手机屏幕电量的时候,我们或在游戏,或在看视频,或在上网,屏幕是一个很耗电的组件,在电量消耗方面,他跟设备上的大多数硬件都不是一个数量级的。
当手机在口袋里的时候。因为屏幕关闭,用户并没有真正的在使用手机。此时的功耗会被CPU ,Network,后台作业等占用。
通常我们在写代码的时候。会注册很多隐式广播来监听一些手机中状态变化,然后在后台开启一个任务。这看起来不经意的行为,其实是对电池电量和用户体验都产生了实质的影响。所以Google在Android的一些新版本中逐步增加了对于后台的优化和限制。就是为了提升电量的续航能力。
后台优化的核心宗旨就是:Reduce(减少), Defer(延迟), Coalesce(合并)
这个结果应该没有让大家失望吧。
如果用户设备未插接电源、处于静止状态一段时间且屏幕关闭,设备会进入低电耗模式。 在低电耗模式下,系统会尝试通过限制应用对网络和 CPU 密集型服务的访问来节省电量。 这还可以阻止应用访问网络并推迟其作业、同步和标准闹铃。
系统会定期退出低电耗模式一会儿,好让应用完成其已推迟的任务。在此维护时段内,系统会运行所有待定同步、作业和闹铃并允许应用访问网络。
在每个维护时段结束后,系统会再次进入低电耗模式,暂停网络访问并推迟作业、同步和闹铃。 随着时间的推移,系统安排维护时段的次数越来越少,这有助于在设备未连接至充电器的情况下长期处于不活动状态时降低电池消耗。
一旦用户通过移动设备、打开屏幕或连接到充电器唤醒设备,系统就会立即退出低电耗模式,并且所有应用都将返回到正常 Activity。
Google Cloud Messaging (GCM) 是一项云端至设备的服务,允许您支持在后端服务与 Android 设备上的应用之间实时进行下游消息传递。GCM 提供了单一持久的云连接;所有需要实时传递消息的应用均可共享此连接。此共享连接使多个应用无需消耗电池即可维持自身单独的持久连接,避免快速耗尽电池,从而显著优化电池消耗。 因此,如果应用需要与后端服务进行消息传递集成,我们强烈建议您尽量使用 GCM,而非维持自身持久的网络连接。
GCM 经过优化,可通过高优先级 GCM 消息用于低电耗模式和应用待机模式。GCM 高优先级消息允许您可靠地唤醒应用访问网络,即使用户设备处于低电耗模式或应用处于应用待机模式也不例外。 在低电耗模式或应用待机模式下,系统将传递消息并允许应用临时访问网络服务和部分唤醒锁,然后将设备或应用恢复到空闲状态。
高优先级 GCM 消息不会影响低电耗模式,也不会影响任何其他应用的状态。这意味着您的应用可以使用这些消息进行有效的通信,同时尽可能减少对整个系统和设备的电池影响。
作为一项常规最佳做法,如果您的应用需要下游消息传递,则应使用 GCM。如果您的服务器和客户端已经使用 GCM,请确保服务对关键消息使用高优先级消息,因为即使设备处于低电耗模式,这也会可靠地唤醒应用。
当screenoff 且non-charging时,进入STATE_INACTIVE
。此时会设置INACTIVE_TIMEOUT,默认为30min
当INACTIVE_TIMEOUT时,进入STATE_IDLE_PENDING
,此时会开启SignificantMotion,并设置IDLE_AFTER_INACTIVE_TIMEOUT,默认为30min.
当IDLE_AFTER_INACTIVE_TIMEOUT时,进入STATE_SENSING
,此时启动AnyMotionDetetor
当AnyMoTionDetetor检测为静止时,进入STATE_LOCATING
,并设置LOCATING_TIMEOUT,默认为30s,并请求当前的Location状态。
当Location状态显示当前位置达到设定的精确标准时,直接进入STATE_IDLE
,否则等到LOCATING_TIMEOUT,进入STATE_IDLE.此时停止AnyMotionDetetor,通过AlarmManager.setIdleUntil 通知AlarmManager进入IDLE,直到指定的alarm到来(这里设置的alarm默认为60min);通知PowerManager/NetworkPolicy/BatteryStas 进入IDLE状态。并发送broadcast: ACTION_DEVICE_IDLE_MODE_CHANGED.
当(5)中设置的alarm唤醒时,进入STATE_IDLE_MAINTAINTENCE
,此时设置一个默认为5min的timeout,同时通知PowerManager/NetworkPolicy/BatteryStas退出IDLE状态
当(6)设置的timeout 到时,再次进入STATE_IDLE
在状态STATE_SENSING
和STATE_LOCATING
,可能会因为AnyMotionDetetor监测到移动或者SignificantMotion检测到有动作而重新进入STATE_INACTIVE
在状态STATE_IDLE_PENDING
,可能会因为SignificantMotion检测到有动作而重新进入STATE_INACTIVE
当screenon 或者 charging 都会重新进入STATE_ACTIVE
为了确保用户获得极佳体验,您应在低电耗模式和应用待机模式下全面测试您的应用。
在低电耗模式下测试您的应用,您可按以下步骤测试低电耗模式:
您可能需要多次运行第二个命令。不断地重复,直到设备变为空闲状态。
前几次调用都是ACTIVE
,为什么呢?因为没有息屏。>.<
后面可以看到就是系统从活跃到低功耗模式的逐步切换。
最后也可以在彻底进入IDLE模式
之后。不停地切换到维修窗口
,来看看我们安排的JOB能否正常工作。
CONNECTIVITY_ACTION
广播(网络状态切换),当然如果是在运行时用context注册的动态广播,仍然生效。ACTION_NEW_PICTURE
,ACTION_NEW_VIDEO
两个事件的广播。这个优化将影响所有应用。而不仅仅是针对Target 24以上的用户了。如果我们的app仍然在使用这些intent,我们应该尽快移除这些,以便可以支持target 24以上的版本,Android Framework提供了多种方式来替换这些隐式广播。例如JobScheduler
和WorkManager
。
当然Google不是那么绝情的,还提供了几种替代方案。
当然Google也为我们提供了电池分析的工具 Battery Historian 有兴趣的同学可以了解一下,后续有空,我也会体验一番,再来分享。先附上Google传送门,请大家科学上网。Analyze power use with Battery Historian
附赠一枚截图: