七、Android性能优化之电量优化(一)

移动开发 来源:阳光小熊 1299℃ 0评论

一、电量消耗理论与分析

写出耗电量低的应用的关键是要透彻理解它的理论以及全部过程。下面将对电量消耗的相关理论知识进行介绍。

1、电量消耗的概念

首先要知道,电量的消耗,主要是指硬件的电量消耗(废话),在电子世界,这种硬件消耗电量来执行任务的过程,叫做超时电流消耗。


硬件消耗电量
硬件消耗电量

同情况下,相同时间内,消耗的电量是不同的。比如使用飞行模式待机,确实可以坚持10多天。但是我们一旦使用手机,比如使用蜂窝式无线数据交换(3G4G)、屏幕保持唤醒状态等,电量就会消耗得很快:

耗电分析
耗电分析

作为开发者,我们很想知道我的应用执行的哪些任务消耗的电量是最多的?这个问题确实会很棘手。

电量优化是方方面面的,比如说减少内存的开销,减少界面的过度绘制,本身就是一种电量优化。

2、电量消耗计算

电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情(所以很多设备都把这个监测电量的功能阉割掉了。)。
唯一可行的方案是使用第三方监测电量的设备,这样才能够获取到真实的电量消耗(因为第三方硬件监测的时候是用的自己的供电而不是用的手机的电量)。
耗电情况,例如:打开屏幕,所有要使用CPU/GPU工作的动作都会唤醒屏幕,都会消耗电量。这和应用程序唤醒设备还不一样。
比如使用叫醒闹钟(wake clock)、AlarmManager、JobSchedulerAPI。因此很难知道自己的应用程序的真实耗电情况。

3、设备待机与唤醒电量消耗分析

为什么要单独拿这个出来讲呢,就是因为,唤醒这个瞬间是非常耗电的,下面允许我慢慢介绍。

先来看看待机状态的电量消耗:


待机状态电量消耗
待机状态电量消耗

待机状态下,电量的消耗是非常少的,这是毋庸置疑的。

使用和唤醒屏幕后:

屏幕唤醒
屏幕唤醒

可以看到,屏幕唤醒的一瞬间是非常耗电的,这里有一条电量使用高峰线。

下面来看看CPU唤醒的曲线(CPU唤醒,屏幕不一定会唤醒):

CPU唤醒时
CPU唤醒时

同样的,CPU唤醒的时候也会有一条电量使用高峰线。

CPU唤醒之后:


唤醒之后唤醒之后
唤醒之后唤醒之后

CPU唤醒之后,设备的耗电不会出现唤醒的时候的高峰线。

值得注意的是当工作完成后,设备会主动进行休眠,这非常重要,在不使用或者很少使用的情况下,长时间保持屏幕唤醒会迅速消耗电池的电量。

结论

设备唤醒的瞬间是有消耗高峰的,因此,当你的工作需要持续的时候,可以考虑保持唤醒状态。

4、无线蜂窝耗电分析

蜂窝式无线也是耗电量非常可怕的,甚至比WIFI更加耗电,因此这里单独拿出来进行分析。

Tips:不使用流量的时候,最好把数据关闭,这样又省电又省流量。

下面开始分析无线蜂窝耗电的过程:

无线蜂窝耗电过程
无线蜂窝耗电过程

如上图所示:

1、当设备通过无线网发送数据的时候,为了使用硬件,这里会出现一个唤醒高峰。
2、接下来还有一个高数值,这是发送数据包消耗的电量。
3、然后接受数据包也会消耗大量电量,也看到一个峰值。
4、保持唤醒状态,耗电比较均衡,很少出现高峰点。

所以我们开启无线模式这个过程非常耗电,那么硬件这块为了防止频繁开启关闭耗电,采取了一个无奈的办法,会在一个小段时间内保持开启模式,防止短时间内还有数据包需要接收。这些数据非常有用,可是不是所有开发者都有这个第三方设备跟踪。但是使用Android L版本就可以利用到新的一系列的工具来优化应用程序的耗电。(这里显然不要考虑兼容性问题,我只是想测电量消耗问题,同一款APP在不同版本的Android上耗电情况应该不会有太大影响,虽然不同Android版本对电量的优化不同,但是我们的分析对象是我们自己的APP本身)

二、电量分析工具Battery Historian的环境搭建与使用

Battery Historian 是一个这样的的工具:可以在 Android 5.0 Lollipop(API 级别21)及更高版本的 Android 设备上检测与电池相关的信息和事件,而在此期间,该设备没有插上电源。它允许应用程序开发人员在时间轴上可视化系统和应用级别的事件,并使用平移和缩放功能,在设备最后一次完全充电之后,可以轻松地查看各种聚合统计信息,可以选择一个应用程序,检查所选择的应用程序对电池指标的影响。此外,它还允许对两个错误报告进行 A/B 比较,突出显示了关键电池相关指标的差异。

环境配置

(1)安装Go编程语言

点击下载go语言
配置GOROOT、GOPATH、PATH环境变量。

GOROOT
GOROOT
GOPATH
GOPATH
Path
Path

检查是否安装成功:cmd 执行 “go version”


(2)安装 Python

下载:https://www.python.org/ 【注意仅支持 python 2.7,python3.0改变很大】

安装

配置环境变量

Paste_Image.png
Paste_Image.png

检查是否安装成功:cmd 执行 “python –V”【注意是大写V】


(3)安装Git

下载:https://git-scm.com/

安装

检查是否安装成功:cmd 执行 “git version”


(4)下载 Battery Historian 源码并且运行
  1. cmd 执行“go get -d -u github.com/google/battery-historian/...”【注意最后有三个点】


下载成功后会在GOPATH(我自己建的工作空间文件目录)下生成src文件夹



  1. 进入到$GOPATH/src/github.com/google/battery-historian目录下方



  2. 运行Battery Historian

  cmd 执行“go run setup.go”【第一次执行要下载,时间会久一些,以后就快些】

ps:http://blog.csdn.net/feitian_666/article/details/52756522 提供了一个在没有下载成功情况下补充“go run setup.go”的方法:手动下载【closure-library】和【closure-compiler】和【flot-axislabels】,解压放到 GOROOT 目录下 third_party 文件夹下方的的 closure-compiler、closure-library 和flot-axislabels 文件夹,如果没有均手动创建。

  cmd 执行 go run cmd/battery-historian/battery-historian.go

  1. 检查/battery-historian是否运行
    登录网址 http://localhost:9999查看是否加载运行battery historian。
    G@~)M7WYR)R@T_(V9P%@5JV.png
    G@~)M7WYR)R@T_(V9P%@5JV.png

使用

(1).初始化

battery-historian工具需要使用bugreport中的Battery History,因此需要如下的操作。
重启adb服务:

adb kill-server
adb start-server

这一步很重要,因为当我们开发时做电量记录时会打开很多可能造成冲突的东西。为了保险起见我们重启adb。
通过以下命令来打开电池数据的获取以及重置:

adb shell dumpsys batterystats --enable full-wake-history
adb shell dumpsys batterystats --reset

上面的操作很重要,因为可以过滤掉不需要的数据。然后断开数据线(防止数据线造成充放电数据干扰),运行自己的APP进行测试。

(2)导出手机的 Bugreport 文件

重新连接USB调试,通过下面的命令获取数据:

adb bugreport bugreport.zip(6.0以及以下的,使用adb bugreport > bugreport.txt导出)

你在哪个目录下执行adb bugreport bugreport.zip 就会在哪个目录下生成 bugreport.zip文件

(3)上传bugreport.zip文件至 http://localhost:9999

最后

注意:7.0以下的,需要使用旧版本的adb工具,不然没法采集,参考文章http://blog.csdn.net/mwq30123/article/details/53888449
注意:官方SDK文档导出文件方式为:adb shell dumpsys batterystats > batterystats.txt。使用python historian.py batterystats.txt > batterystats.html查看数据。这是battery-historian老版本的使用方式. 目前Battery Historian已更新2.0版本, 推荐使用bugreport方式导出数据分析, 可以看到更多信息。
注意:模拟器可能获取不到有用的电量数据,网页没有显示电量信息,如下图所示:

模拟器的bugreport
模拟器的bugreport
真实手机的bugreport
真实手机的bugreport

特别感谢:
小楠总
动脑学院Ricky
张小侨

关闭

IT问道推荐

银行贷款频频被拒?
“Dr信用牛牛”让你远离信用污点 国内首家信用健康管理平台免费为你提供信用修复方案