Android APP 的电量消耗也是APP 衡量性能的一项指标,一款优秀的应用应该尽可能的消耗更少的电量。在实际开发中,我们可以使用Batterystats 和 Battery Historian 来对设备应用的耗电情况进行分析,从而确定我们开发的应用是否耗电严重,如果是则需要进行优化。
Batterystats是一个包含在Android框架中的工具,用于收集设备上的电池数据。我们可以使用adb将收集的电池数据转储到开发机器上,并创建一个报告,我们可以使用Battery Historian进行分析。Battery Historian将来自Batterystats的报告转换为可在浏览器中查看的HTML可视化文件。
一. 安装 Battery Historian
安装Battery Historian 最简单的方法是使用Docker 安装,所以要先安装 Docker。
安装Docker 比较简单,只需要从官网下载 dmg 文件,然后像安装其他软件一样,双击、拖拽即可。安装完成之后,在命令行运行
docker --version
验证并查看版本。
接下来可以安装Battery Historian 了,只需要一行命令即可
docker run -p 9999:9999 gcr.io/android-battery-historian/stable:3.0 --port 9999
Docker 会自动下载Battery Historian 的镜像并运行,在运行成功后会有这样一条提示
这时,在浏览器地址输入:localhost:9999 即可打开Battery Historian 的开始页,
上传电量统计文件即可进行分析查看。
二. 收集电量统计数据
上面安装的Battery Historian 只是一个分析数据的工具,那么设备耗电量的统计数据从何而来,就是我们上面提到的Batterystats 来收集的,现在做收集数据工作需要下面几步:
1. 连接手机,重启adb 服务,执行如下命令
adb kill-server
然后执行一条adb 命令重启服务
adb devices
2. 重置电量收集数据
因为设备一直在后台收集电量信息和其他的调试信息,所以需要将旧的信息清除,重新开始收集
adb shell dumpsys batterystats --reset
如果不执行reset 命令,可能得到的数据会非常大。
3. 断开数据线,以免数据线充电给收集数据造成影响,然后开始对应用进行一些使用操作。
4. 一顿操作之后,重新连接手机,并使用devices 命令确保已经连接
5. 导出数据
adb shell dumpsys batterystats > [path/]batterystats.txt
path 是我们指定的路径,如果不指定将存在根目录下
导出bugreport 文件
// Android 7.0 及以上系统
adb bugreport > [path/]bugreport.zip
// Android 6.0 及以下系统
adb bugreport > [path/]bugreport.txt
注意,在执行bugreport 命令时,可能会出现如下错误:
Failed to get bugreportz version, which is only available on devices running Android 7.0 or later.
Trying a plain-text bug report instead.
那是因为platform-tools 的版本是7.0 以上,所以adb 的版本较高,然而设备版本却在7.0 以下,就会出现这个问题,解决方法是下载 低版本的platform-tools ,使用低版本adb。
6. 将上一步导出的数据上传到Battery Historian 页面,只需点browser 选择bugreport.txt/zip,然后点右下角 submit 即可。
上传成功后,会生成一个图表,可以根据图表显示的信息对应用耗电情况进行分析。
三. 分析数据
在导入数据之后,我们会得到一些分析图表,由于截图大小限制,下图只是一部分
-
第一部分
图中主要有标记的三个部分需要关注
① 可以从下拉菜单中添加要查看的指标
② 各个指标,我们可以主要关注一下下面这些:
battery_level 电量,可以看出电量的变化。比如上图中的数据显示刚开始电量是100%,然后在第11秒-12秒中间的某个时刻降到了99%。
screen 屏幕是否点亮,这一点可以考虑到睡眠状态和点亮状态下电量的使用信息。
top app 该栏显示当前时刻哪个app处于最上层,就是当前手机运行的app,用来判断某个app对手机电量的影响,这样也能判断出该app的耗电量信息。该栏记录了应用在某一个时刻启动,以及运行的时间,这对我们比对不同应用对性能的影响有很大的帮助。
wake_lock* wake_lock 该属性是记录wake_lock模块的工作时间。是否有停止的时候等
CPU running:CPU的运行状态,是否被唤醒。如果把鼠标放到上面去,还能看到更多的信息,如CPU唤醒的原因。
wake_lock_in* wake_lock有不同的组件,这个地方记录在某一个时刻,有哪些部件开始工作,以及工作的时间。
gps gps是否开启
WiFi supplicant:wifi是否开启
WiFi signal strength:wifi强度
Audio:音频是否开启
phone_in_call 是否进行通话
Sync 是否跟后台同步. 可以把鼠标停在某一项上面。可以看到何时sync同步 启动的,持续时间Duration多久。电池容量不会显示单一行为消耗的具体电量,这里只能显示使用电池的频率和时长,你可以看分时段的剩余电量来了解具体消耗了多少电量。
Job 后台的工作,比如服务service的运行。从下面图中可以看到qihoo的AppStore和鲁大师都在运行后台服务。
data_conn* 数据连接方式的改变,上面的edge是说明采用的gprs的方式连接网络的。此数据可以看出手机是使用2g,3g,4g还是wifi进行数据交换的。这一栏可以看出不同的连接方式对电量使用的影响。
status 电池状态信息,有充电,放电,未充电,已充满,未知等不同状态。 这一栏记录了电池状态的改变信息。
mobile signal strength 手机信号状态的改变。 这一栏记录手机信号的强弱变化图,依次来判断手机信号对电量的影响。
health 电池健康状态的信息,这个信息一定程度上反映了这块电池使用了多长时间。 这一栏记录电池状态在何时发生改变,上面的图中电池状态一直处于good状态。
plugged 充电状态,这一栏显示是否进行了充电,以及充电的时间范围。例如上图反映了我们在09:10 后的某个时间点插入了数据线,然后一直持续了数据采集结束。
plug 充电方式,usb或者插座,以及显示连接的时间。 这一栏显示了不同的充电方式对电量使用的影响。
③ 将鼠标悬停在条上,即可查看有关该指标的详细信息以及时间线上特定点的电池状态。
2. 第二部分
① System Stats选项卡包含系统范围的统计信息,如单元信号级别和屏幕亮度。这些信息提供了设备发生情况的整体情况。这对确保没有外部事件影响我们的测试特别有用。
② App Stats选项卡包含有关特定应用程序的信息。可以使用左侧 ③ 对应用程序进行排序。也可以通过④ 来选择一个特定的应用程序来查看统计信息。
使用Battery Historian 可以帮助我们分析应用是否有以下行为:
过度频繁地发出唤醒alarms(每10秒钟或更少)
持续持有GPS锁
每30秒或更短时间安排一次 job
计划每30秒或更短时间sync 一次
比我们预期更频繁地使用蜂窝数据
四. 导致电量消耗过快的原因
Android系统为了尽可能的增加设备的续航,会不断的关闭各种硬件模块来节省电量。当我们的App在设备处于休眠状态下想要执行一次网络请求的时候;首先需要唤醒设备,接着会发送数据请求,然后等待服务端返回的结果,最后再经过一段时间的等待才会慢慢进入休眠状态。
尽可能地避免唤醒锁或批量操作以避免频繁的唤醒设备即使屏幕没有被点亮CPU也会保持运行状态,通过AlarmManager可唤醒设备,而项目中不限制的滥用,导致系统被频繁唤醒;Android 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,再加上不恰当的使用WakeLock最终没有合理释放掉,使得系统长时间无法进入休眠,势必导致高耗电,可参考(android设备休眠[http://www.cnblogs.com/kobe8/p/3819305.html])
CPU和网络耗电方面,主要是减少I/O操作(包括数据库操作),大量的计算;减少网络网络请求次数和数据量,将不重要的操作放在用户充电或已经连接至WiFi的时候。分析和记录之类的操作不需要实时进行。
传感器方面设备屏幕亮度、颜色背景等需要考虑,但除了阅读类等应用,一般是不太考虑屏幕消耗的。更多的是对GPS的使用注意,减少无用的GPS请求和及时关闭GPS搜索。