作者:京东物流 刘华宇
前言:
随着手机在生活中的占比越来越高,屏幕尺寸越来越大,刷新率越来越高,手机电池电量和功耗也成为了影响用户体验的一个重要因。高功耗不仅仅会引发用户的电量焦虑,而且也会导致手机严重发热变成“暖手宝”,从而降低了用户的使用意愿。而影响功耗的因素有很多,下面就为大家介绍一下Android应用功耗的基础知识、功耗的组成以及功耗分析做一个分享
功耗的基础知识
我们先看一下为什么手机上使用mA(电流值)来表征功耗水平,用mAh(物理意义上是电荷值)来表征能耗水平。先回忆两个初中物理公式:
P = I X U
E = P X T 即 E = I X U X T
能耗(E):即能量损耗,指一段时间内消耗的总能量,单位是焦耳(J)
功耗(P):即功率损耗,指单位时间内的能量消耗,反应消耗能量的速率,单位是瓦特(W)
电流(I):指手机电池放电的电流值,手机一般用mA做为单位
电压(U):指手机电池放电的电压值,标准放电电压3.7V,充电截止电压4.2V,放电截止电压2.75V(不同设备可能会存在差异)
电池容量:手机一般用mAh做为单位,表征电池以标准电压放电的时长
手机正常状态下都会以恒定的放电电压进行工作,一般为3.7V,是一个常量,那么忽略掉上面两个公式中的电压(U),我们就可以用电流(mA)表征功耗,mAh表征能耗了
功耗的组成
在Android Developer文档中将电池使用情况信息拆分成了电池使用情况统计信息和电源配置文件两部分。其中电池使用情况统计信息是这样描述的
框架可通过跟踪设备组件在不同状态下维持的时间来自动确定电池使用情况统计信息。当组件(WLAN 芯片组、手机无线装置、蓝牙、GPS、显示屏和 CPU)状态发生改变(开/关、空闲/全功耗、低/高亮度等)时,控制服务会向框架中的 BatteryStats 服务报告状态改变信息。BatteryStats 会不断地收集信息,并存储这些信息以供在设备重新启动后继续使用。该服务不会直接跟踪电池中消耗的电流,而是通过收集计时信息来估算不同组件所消耗的电量。
所以我们可以将所有应用的耗电最终转化为手机组件的耗电。
CPU、屏幕、WiFi和数据网络、GPS以及音视频通话都是我们日常的耗电大户,各个硬件模块都会耗电,而且不同的硬件耗电量也不太一样,那么我们如何评估不同应用的耗电情况呢?这就涉及到了另一部分电源配置文件power_profile.xml
设备制造商必须在
/frameworks/base/core/res/res/xml/power_profile.xml
中提供组件的电源配置文件。 如需确定电源配置文件的有关数值,请使用测量设备耗电量的硬件,并执行需要其耗电量信息的各种操作。测量执行这些操作时的电量使用情况并计算各项值(在适当情况下与其他基准操作的电量消耗做对比所得的差异值)。 电源配置文件的目的在于适当地估算电量消耗情况,电源配置文件的有关数值以电流(安培)表示。Android 框架用电流乘以子系统处于激活状态的时间,并计算毫安时值,然后将此值用于评估应用/子系统消耗的电池电量。
power_profiler.xml文件定义了不同模块的电流消耗值,Android系统的电量计算也是通过读取配置文件中的数值而已,不同的厂商具体的数值都不太一样,我们可以通过下面的方式获取:
•从设备中导出/system/framework/framework-res.apk文件
•使用反编译工具对导出文件framework-res.apk进行反编译
•查看power_profile.xml文件在framework-res反编译路径:/res/xml/power_profile.xml
Google根据配置文件提供了一套通用的期间耗电计算模型,这里以wifi为例。WiFi不同状态下的耗电差异非常明显,如图中所示分为了wifi.on(当 WLAN 打开,但未接收、发送信号或执行扫描时消耗的额外电量),wifi.active(通过 WLAN 发送或接收信号时消耗的额外电量),wifi.scan(WLAN 正在扫描无线接入点时消耗的额外电量)。根据WiFi在不同状态下的状态时长统计数据,乘以对应的电流,就可以得到wifi的耗电了
功耗测量
目前行业内比较常用的集中电量测试方法的对应的优缺点大概有这样几种
序号 | 测试方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
1 | 稳压电源+电流仪 | 整机电流 | 可以测试整机电流,并且数据精确 | 需要准备硬件工具,且不能准备测试具体应用消耗电量 |
2 | dumpsys batterystats | App电量 | 有耗电量的详细数据 | 结果可读性比较差 |
3 | 系统耗电排行 | App电量 | 简单直观 | 没有详细的数据 |
4 | Battery Historian | App电量 | 结果直观,有耗电量的详细数据 | 只适用于Android5.0及以上系统 |
1.PowerMonitor
目前业内最通用的整机耗电评估方法就是通过PowerMonitor外接电源的方式,高频率高精度采集电流进行评估。常用需要需要精细化确认耗电情况,尤其是后台精致,灭屏等状态下的电流输出,厂商的准入测试等。虽然PowerMonitor测试结果最为准确,但是需要拆机非常麻烦
2.dumpsys batterystats
对于系统的电量消耗情况,我们可以通过dumpsys batterystats导出
adb shell dumpsys batterystats > battery.txt
adb shell dumpsys batterystats --reset
BatteryStatsService是对外的电量统计服务,具体的统计工作是由BatteryStatsImpl来完成的,BatteryStatsImpl会为每一个应用创建也一个UID实例来监控应用的系统资源使用情况
3.系统耗电排行
厂商提供的耗电排行也可以用来查看一端时间内的应用耗电情况。比如华为的耗电排行中,对硬件和软件耗电进行了拆分了,并给出每个应用的具体耗电量
4.Battery Historian
Battery Historian是Google官方提供的一种工具,用于分析耗电数据
Batterystats 是包含在 Android 框架中的一种工具,用于收集设备上的电池数据。您可以使用adb将收集的电池数据转储到开发机器,并生成可使用 Battery Historian 分析的报告。Battery Historian 会将报告从 Batterystats 转换为可在浏览器中查看的 HTML 可视化内容。
安装Battery Historian
可以通过Docker镜像方式或者通过源代码构建的方式进行安装,参考连接:安装Battery Historian
如果感觉搭建过程繁琐,可以直接使用:https://bathist.ef.lc/
Battery Historian的使用方法
1.使用adb将移动设备连接到计算机
2.重置电池数据收集,设备始终会在后台收集 Batterystats 和其他调试信息。重置操作会清除旧的电池收集数据。如果不重置,输出内容会非常大
adb shell dumpsys batterystats --reset
1.断开设备与计算机的链接,以便仅通过电池供电
2.执行需要测试的场景
3.重新将设备连接到计算机
4.生成原始数据报告
对于Android 7.0及更高版本的设备:
adb bugreport [path/]bugreport.zip
对于Android 6.0及更低版本的设备:
adb bugreport [path/]bugreport.txt
1.在浏览器中打开Battery Historian,点击Browse,选择上面创建生成的bug报告文件
2.点击Submit,Battery Historian将会打开根据Batterystats数据创建的图表
其中标号的意义:
•标号1:从下拉列表中可以添加其他指标
•标号2:将鼠标悬停在信息图表上可以查看有关每个指标的详细信息,包括图表中使用不同颜色代表意义的介绍
•标号3:将鼠标悬停在某个条目上可以查看该指标的更多详细信息,以及时间线上特定定的耗电量
这是整个手机状态图,包括手机电量,CPU使用时长,WiFi信号强度,手机温度变化等等,都在上面详细的用图表展示出来了。
Battery Historian除了能提供系统层面的信息,还能够针对指定App的可视化数据和表格信息,主要包括:
•Device estimated power use:预估耗电量
•Networks Information:app网络信息
•Wakelocks:唤醒锁信息,一般和业务强相关
•Services:服务信息,查看app开启的services信息
•Process info:进程信息
•Sensor Use:传感器信息
其中标号的意义:
•标号1:System Stats分组包含系统级别的数据,比如屏幕亮度等。这一栏显示了系统发生的总体情况,可以用来测试是否存在外部影响事件
•标号2:App Stats分组包含针对指定App的详细信息
•标号3:可以根据不同的分类标准对App进行排序
•标号4:在下拉列表中选择指定的App后可以在App Stats中查看具体信息。App Stats所展示的信息都是所选定的App产生的数据,不会收到外部因素的影响
通过对上述数据进行分析,我们就可以有针对性的开展功耗优化,我们可以减少高功耗器件的使用情况,进而降低功耗