凡事谦虚、温柔、忍耐、用爱心互相宽容,用平和彼此联络,竭力保守圣灵所赐合而为一的心。----以弗所书4:2-3
battery historian 是什么
battery historian是用go语言开发的一个电池耗电分析工具,Android 5.0以后的版本可以使用它。其官方文档地址https://github.com/google/battery-historian。
环境配置
安装Go语言
从go官网http://golang.org/doc/install 下载安装 。没找到国内镜像,漫长的下载过程。mac版本下载pkg包后点击安装,此后go已经安装好了,为了使用方便还需要配置下环境变量。
$ cd mydisk # 进入任意目录
$ mkdir -p go-workspace/bin # go编译后的执行文件会放在该目录下
$ mkdir -p go-workspace/src # 放置go语言编写的项目的源码
#以后的项目结构大概如下图
#bin/
# testA # 可执行命令
# testB # 可执行命令
#src/
# projectA #A工程文件
# projectB #B工程文件
#为了不用每次配置go的环境变量,将下面内容添加到.bashrc文件中
export GOPATH=mydisk/go-workspace
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN
下载配置battery historian
go get -d -u github.com/google/battery-historian/...
...要带上,这样才会将相关的依赖也同步下载下来。等待运行完成后,去$GOPATH/src下看到github.com目录,battery-historian就放在其下。
$ cd go-workspace/src/github.com/google/battery-historian
$ go run setup.go #漫长的等待,它需要联网下载以来库,编译Javascript等。
如果你所在地区被墙的厉害,可能只能看着Downloading Closure library...
干着急。去setup.go文件搜索Closure,原来一直在龟速下载
http://dl.google.com/closure-compiler/compiler-20160208.zip。这时可以手动下载该包,解压到src/github.com/google/battery-historian/third_party/closure-library
。然后在去运行go run setup.go
启动battery historian服务器
$ cd $GOPATH/src/github.com/google/battery-historian
$ go run cmd/battery-historian/battery-historian.go
必须要在$GOPATH/src/github.com/google/battery-historian directory目录下运行。
然后在浏览器中打开http://localhost:9999。就可以上传bugreport.txt进行分析了。
分析battery historian
获取bugreport
Android 6.0之前:
$ adb bugreport > bugreport.txt
Android 6.0之后:
$ adb bugreportz
# 根据提示adb pull出生成的压缩文件,然后解压
# 某些手机上也可以使用旧的命令,执行完成后会生成一个压缩包和bugreport.txt,上传压缩包也能解析。
$ adb bugreport > bugreport.txt
分析报告示例
浏览器中打开http://localhost:9999。上传bugreport.txt进行分析。下图为上传后生成的报告。
半离线使用historian.py
historian.py是battery historian工具包下的一个脚本,它用来解析battery stats。
在分析前,先用命令
adb shell dumpsys batterystats --reset
清除测试前的电量数据,保证测试环境的干净,避免旧的脏数据影响。
如果要详细的分析wakelock事件,执行如下命令
adb shell dumpsys batterystats --enable full-wake-history
如果还要分析更加详细的kernel层wakelock,则需要root手机,按如下操作。
$ adb shell
# 设置trace事件
$ echo "power:wakeup_source_activate" >> /d/tracing/set_event
$ echo "power:wakeup_source_deactivate" >> /d/tracing/set_event
# 设置一个8m的trace空间,防止trace空间溢出,抓取的log被冲掉
$ echo 8192 > /d/tracing/buffer_size_kb
$ echo 1 > /d/tracing/tracing_on
然后断开usb连接,避免连接usb线充电的干扰。此后愉快的玩耍手机,复现耗电问题。
一小段时间后,执行
adb shell dumpsys batterystats > batterystats.txt
收集测试期间的电量数据,该数据被保存在batterystats.txt文件中。
这个时候就该historian.py出场了。如果你是clone的battery historian包,那么该脚本位于scripts/historian.py下。执行命令
python historian.py batterystats.txt > batterystats.html
用chrome打开转换生成的batterystats.html文件,注意这个时候保持电脑连网,只要打开过一次浏览器加载了需要的js后面就可以不用在连线了。之所以叫半离线使用就在这。得到如下图的数据。
对照上图解释下各项数据的含义。按行分析图表,图表中的数据不代表该项的耗电量,被着色只是表示该项处于激活状态,它确实在耗电,但具体耗了多少电,图表是量化不出来的,只能定性的分析它耗电了。另外图表中耗电数据的呈现方式也不是按进程来组织的,而是按照耗电组件的方式排布,比如着大红色top行表示当前运行在前台的进程,切换前台进程,不管当前前台是哪个应用都始终被归类在top行里。
在上一张官方的图例说明。
对照官方图例介绍下各行的含义。
- battery_level: 开始测试时的电量,之前抓取的图可以看到电量是100,满电状态。
- top: 前台应用,如果要分析应用的耗电情况,那么在测试期间,就该保证应用一直处于前台。
- wifi_running: wifi连接情况下的耗电情况,我抓取时没开wifi,因此没有看到该项。
- screen: 亮屏状态,可以看到图表中该项着色有间隔,这是因为实验期间我关闭过屏幕,每关闭一次屏幕,着色就被打断。
- phone_in_call: 记录打电话的耗电状况。
- wake_lock: 应用被唤醒,该项数据非常有意义,频繁唤醒应用是高耗电的前兆,如果该项看到众多色块,往往需要重点去check。
- running: cpu在运行,同样表明在耗电。
- wake_reason: 被唤醒的原因,去代码看该次唤醒是否有必要,是否能将多个任务集中在一起,唤醒一次去执行。
mobile_radio: BP侧耗电,通常是指SIM卡,数据链接。该栏过多着色,间隔多。表示功耗也会高。
在细说下一点。有时数据量大,很多色被挤压在一起不太方便观察,此时可以用放大功能,类似systrace工具中的w键,但该工具做的没systrace便利,还需要手动填写缩放比例,具体下图我放大了1000.
放大后看看top项。
这里的u0a99代表的是进程id,某些手机能直接显示出进程名,如果厂商该ROM,可能导致进程名无法显示出来,这时可以去ps进程id,方向查到对应的包名。如果看的细心点还可以发现u0a99之后出现了u0a114,这个是因为实验时我切换了前台应用,可以看到这个动作很精确的被historian捕捉到了。
电量监控分析
从官方文档看该工具还能进行电量监控,但依赖源码的某些文件。暂时还未完全配置好,先挖个坑,以后回填。
monsoon.py 使用前需要安装
- gflags
$ git clone https://github.com/google/python-gflags.git
$ cd python-gflags
$ sudo python setup.py install
- pyserial
$ git clone https://github.com/pyserial/pyserial.git
$ cd pyserial
$ sudo python setup.py install