背景
迈入移动时代之后,我们的工作和生活已经离不开手机了。每个人都希望从早上醒来开始,到晚上给手机充电之前,手机的电量能够支撑我们一天的工作,社交,娱乐。在强烈的用户需求下,整个安卓生态的角色,无论是设备厂商,谷歌还是应用公司,都自发的贡献自己的力量来做耗电优,这次分享主要探究各方的视角下,所提出的耗电优化方案,到底发挥了自身哪些优势,遇到了哪些问题,权衡了哪些事情,以及关注什么利益。
安卓生态下各方视角耗电优化关系图如下:
通用优化原则
-
减少硬件休眠唤醒次数:硬件的低功耗模式电流,与正常工作电流能达到百倍到千倍的差距,因此减少唤醒次数非常重要。例如不要唤醒手机只发送很小的数据到后端,可以合并到一起发送
-
保证硬件正常进入休眠:例如应用不要因为长时间持有wake lock导致手机无法休眠
-
减少硬件使用时长:资源使用时间越少,自然越省电。例如获取实时位置时,gps扫描频率够用就行
-
优化硬件使用时机:例如延迟任务到手机充电之后再执行
功耗公式
-
总耗电=模块1耗电+模块2耗电+...+模块n耗电
-
模块x耗电(mAh) = 模块x行为1电流(mA) * 模块x行为1耗时(h) + 模块x行为2电流(mA) * 模块x行为2耗时(h) +... +模块x行为n电流(mA) * 模块x行为n耗时(h) + 模块x低功耗模式时间的耗电 + 模块x等待进入低功耗模式时间的耗电
(电能 = 电压 * 电流 * 时间,而手机电压经过稳压之后是恒定的,所以公式只需要考虑电流和时间)
举例如下:下面两个例子虽然工作时间都是10ms,但是唤醒硬件的次数会导致等待进入低功耗模式时间不同,最终导致功耗相差很大,因为低功耗模式电流,与正常工作电流能达到百倍到千倍的差距。
20ms=10ms工作时间 + 2ms等待进入低功耗模式时间 + 8ms低功耗模式时间
20ms=两次5ms工作时间 + 4ms等待进入低功耗模式时间 + 6ms低功耗模式时间
谷歌视角的耗电优化
谷歌提供规范的电源管理机制,体系而规范的治理耗电,同时作为中间桥梁连接设备和应用,防止耗电治理变得混乱,这样谷歌能够让整个安卓生态吸纳更多的设备和用户。从中我们可以了解到比较全面的电源管理,所以先介绍一下谷歌视角的解决方案。
通过Doze,App Standby,Battery Saver机制,将硬件资源分配给最需要他们的应用,进而最大程度的降低耗电。
-
Doze:通过合并应用的后台活动降低耗电
-
App Standby:根据app的使用频率,限制设备资源的使用,进而降低耗电
-
Battery Saver:用户主动进入省电模式
Doze
名词简单介绍
-
Job:后台执行的任务,会持有wakelock防止系统休眠,可以设定约束条件智能的执行,例如指定特定的网络、是否只在充电时执行等
-
Sync:用于跟后端通信的任务
-
Wakelock:持有之后,可以防止屏幕关闭之后系统进入休眠状态
-
Alarm:闹钟的实现机制,可以将系统从休眠状态中唤醒
工作模式
如果设备是电池供电,并且静止不动一段时间,同时屏幕是关闭的,同时设备没有持有Wakelock阻止设备休眠,设备将进入Doze模式,利用linux内核原生支持的休眠模式进入休眠,限制cpu,网络,Gps/Wifi的扫描,同时延迟所有应用的后台任务如Jobs,Syncs,延迟Alarms,将他们合并到一起在maintenance window(周期性的唤醒)的时候执行。并且随着Doze模式越来越久,maintenance window执行的时间间隔会逐渐拉长,直到不满足Doze的条件,例如移动了手机,打开了屏幕,手机充电了,出现了alarm。通过这种机制,可以预见到即使晚上睡觉的时候忘记充电了,第二天醒来手机还能是有电的。
App Standby
工作模式
系统会根据应用使用频率将其放置在五个优先级中的一个,从而限制应用对硬件资源的请求。
五种状态
-
Active:表示用户正在使用应用程序,例如:
-
启动了一个activity
-
正在运行一个后台服务
-
有一个关联了前台应用的content provider/sync adapter(安卓一个封装了设备和服务器之间传输数据的框架)
-
点击了应用的通知
-
Working set:如果一个应用经常运行,但当前不是Active的,那么它就是Working set中。例如用户使用时间很长的社交媒体应用。除了直接使用的应用,间接使用的应用也会被提升到Working set。
-
Frequent :表示一个应用定期的使用。例如用户每天使用的健身应用
-
Rare:表示一个应用不经常使用。例如只在住酒店时才能运行的应用。
-
Never:表示已经安装了,但从未运行的应用。
具体限制
Battery Saver
用户主动进入省电模式,谷歌和设备厂商都会修改这里来对app做更多的限制,例如:
-
app还没有进入空闲状态的时候,就激进的设置app待机模式
-
后台执行限制覆盖所有应用程序
-
屏幕关闭时,禁用Location服务
-
后台app不允许访问网络等等
设备厂商视角的耗电优化
硬件选型
电池选型
英特尔创始人之一戈登·摩尔(Gordon Moore)曾经提出来过摩尔定律,其内容是当价格不变时,集成电路上可容纳的元器件的数目,每隔18-24个月便会翻倍,性能也会翻倍。摩尔定律让硬件如内存,CPU、 flash,一直都在向前展,但是手机上有一个重要部件多年来都没有革命性的突破,那就是电池技术,就连性能也会被功耗限制住。
而厂商优化电池的主要思路就是更慢的耗电和更快的充电。
-
更慢的耗电:例如增大电池容量,但是电池容量也会受限于手机空间,以及过大会有安全问题,例如三星爆炸事件。还有华为资助研究石墨烯新电池材料,但是目前也只是在实验室阶段。
-
更快的充电:各种快充,闪充技术,例如OPPO“充电 5 分钟,通话 2 小时”
其他硬件选型
这些硬件都会连接到电池,这些硬件的选型需要在性能,价格,功耗三者中进行权衡,这取决于产品的卖点是低价,高性能,还是续航时间长。其中屏幕,CPU,WiFi 和数据网络、GPS 都是常见的耗电大户
电路设计
选型之后会交由硬件工程师设计电路,做好工作功耗和待机功耗的检测工作,测试是否有漏电现象,从电路设计层面优化功耗
驱动适配
这里的关键是保证硬件休眠的正常,当硬件不使用的时候,所有硬件资源都要进入低功耗模式,所有驱动的suspend相关的逻辑都要是正常的,并且是最优的。
Framework优化
核心手段是硬件资源的合理限制和合理调度,例如
-
CPU 大小核频率不同,会灵活地为不同任务分配相应的核
-
系统动态调整频率
-
限制进程保活
-
禁止app对某些频繁变化的广播响应
-
alarm对齐,网络心跳唤醒对齐,即是把这些任务合并在一起统一唤醒执行
-
加大系统资源的限制:例如释放waklock锁、禁止gps location调用、关闭wifi 扫描或见啥扫描频率,优化扫描算法避免无效的低信号质量wifi。
-
对不常用的应用进行针对性优化,灭屏强行释放waklock锁、禁止gps location调用、关闭wifi,降低扫描频率等
-
GPS方案合并多app上报,控制频率;
-
屏幕高Hz功耗:由于90、120Hz高帧率做出了更流畅的体验,但不是所有app都需要120Hz。针对不同app进行针对性的开启或关闭高Hz
-
触摸屏:优化扫描频率、点击坐标算法优化等。
-
省电模式加大限制
应用视角的耗电优化
从应用的视角会同时考虑到设备厂商,谷歌的限制和优化特点,也会考虑到用户的特点。
耗电问题
怎么定义一个电量问题?
当功能与电量不相符的时候,就可以看作一个电量问题,并且无论是严重耗电,还是轻微耗电问题,都会随着时间的推移而放大
电量主要去了哪里?
屏幕开启:前台应用在执行,此时屏幕最耗电
屏幕关闭:后台应用在执行,此时cpu,网络最耗电
耗电评测
目前安卓是能采用估算的方式进行量化,Android 系统要求不同的厂商必须在 /frameworks/base/core/res/res/xml/power_profile.xml 中提供组件的电源配置文件。通过adb shell dumpsys batterystats这种方式即可获得估算结果
这种估算方式会出现不准的情况,但是能帮助归因。由上面的公式可以知道,唤醒次数越多的时候,这种计算方式越不准。
耗电优化
可以发挥对业务和用户熟悉的优势,将功能设计的更加合理,例如:
-
结合业务功能,看能否推迟到充电的时候执行,例如等到充电了再上报数据到后端
-
防止出现高cpu的问题
-
不要唤醒手机上报很小的数据,可以合并在一起上报,减少唤醒次数
-
后台程序活跃导致过度的唤醒:例如alarm太频繁,可以多使用标准的库例如WorkManager API,JobScheduler,SyncManager这些框架,将wakelock的释放,任务的延迟,任务出发的时机都交给这些库。如果一定要自行申请wakelock,可以设置一个超时时间,防止没有释放wakelock导致手机无法休眠
-
控制任务绑定绑定大小核
-
跟厂商合作控制cpu频率
-
合理的使用gps扫描频率,不影响功能的情况下降低耗电
耗电工具
通用工具