程序性能优化之耗电优化(四)上篇

阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

本篇文章将最后从以下两个方面来介绍耗电优化:

  • 【Doze 和 StandBy模式】
  • 【Battery Historian 使用】

一、 Doze 和 StandBy模式

1.1 Doze低电耗模式

Android 6.0(API 级别 23)引入了低电耗模式,当用户设备未插接电源、处于静止状态且屏幕关闭时,该模式会推迟 CPU 和网络活动,从而延长电池寿命。而 Android 7.0 则通过在设备未插接电源且屏幕关闭状态下、但不一定要处于静止状态(例如用户外出时把手持式设备装在口袋里)时应用部分 CPU 和网络限制,进一步增强了低电耗模式。

 
19956127-f73dbd4e65ffdd8d.png
 

当设备处于充电状态且屏幕已关闭一定时间后,设备会进入低电耗模式并应用第一部分限制:关闭应用网络访问、推迟作业和同步。如果进入低电耗模式后设备处于静止状态达到一定时间,系统则会对 PowerManager.WakeLock、AlarmManager 闹铃、GPS 和 WLAN 扫描应用余下的低电耗模式限制。无论是应用部分还是全部低电耗模式限制,系统都会唤醒设备以提供简短的维护时间窗口,在此窗口期间,应用程序可以访问网络并执行任何被推迟的作业/同步。

1、暂停访问网络。
2、系统将忽略 wake locks。(Doze模式下获取WakeLock无效,白名单下可以获取PARTIAL_WAKE_LOCK)
3、标准 AlarmManager 闹铃(包括 setExact() 和 setWindow())推迟到下一维护时段。 如果您需要设置在低电耗模式下触发的闹铃,请使用 setAndAllowWhileIdle() 或setExactAndAllowWhileIdle()。 一般情况下,使用 setAlarmClock() 设置的闹铃将继续触发 — 但系统会在这些闹铃触发之前不久退出低电耗模式。
4、系统不执行 Wi-Fi 扫描。
5、系统不允许运行同步适配器。
6、系统不允许运行 JobScheduler。

1.2 StandBy 待机模式

应用待机模式允许系统判定应用在用户未主动使用它时处于空闲状态。 当用户有一段时间未触摸应用时,系统便会作出此判定,以下条件均不适用:

1、用户显式启动应用。
2、应用当前有一个进程位于前台(表现为 Activity 或前台服务形式,或被另一 Activity 或前台服务占用)。
3、应用生成用户可在锁屏或通知托盘中看到的通知。

当用户将设备插入电源时,系统将从待机状态释放应用,从而让它们可以自由访问网络并执行任何待定作业和同步。 如果设备长时间处于空闲状态,系统将按每天大约一次的频率允许空闲应用访问网络。

在低电耗模式和应用待机模式下进行测试

adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step

可能要执行第二个命令多次。

 
19956127-43c8afd188224aba.png
 

在应用待机模式下测试您的应用
通过运行以下命令强制应用进入应用待机模式:

 adb shell dumpsys battery unplug
 adb shell am set-inactive <packageName> true

使用以下命令模拟唤醒应用:

 adb shell am set-inactive <packageName> false
 adb shell am get-inactive <packageName>

申请白名单

 
19956127-593162963cab51c6.png
 
 
19956127-9f12625dbf294d9d.png
 

二、Battery Historian 使用

battery-historian工具需要使用bugreport中的BatteryHistory

1. 先断开adb服务,然后开启adb服务

adb kill-server 这一步很重要,因为当我们开发时做电量记录时会打开很多可能造成冲突的东西。

为了保险起见我们重启adb。

adb devices就会自动连接查找手机。当然也可以adb start-server。

2. 重置电池数据收集数据,我们在开始的时候需要通过以下命令来打开电池数据的获取以及重置:

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

adb shell dumpsysbatterystats –reset

执行的效果如下:

 
19956127-b2042a2813b08827.png
 

上面的操作相当于初始化操作,如果不这么做会有一大堆的干扰的数据,看起来会比较痛苦。

然后把数据线直接拔掉(防止数据线造成充放电数据干扰),现在做一些测试,手动或者跑一些自动化的case

都行。经过一段时间后,我们重新连接手机确认adb连上了,运行下面这条命令来将bugreport的信息保存到

txt文档中:

adb bugreport > bugreport.txt

或者用下面的命令也可以:

adb shell dumpsys batterystats > batterystats.txt

adb shell dumpsys batterystats > com.example.android.sunshine.app >batterystats.txt

加上包名可以限制输出的数据是我们要检测的。

后面这种方法生成的TXT文件是没法上传到battery-historian服务上面进行分析的,因为不兼容。

但是这个txt的数据可读性不强。接下来我们就要用到这个

battery-historian工具了。

到此我们有两种方式分析这个文件:(historian-V1之前的版本和historian-V2最新的版本)

historian-V1之前的版本分析方式:

将txt文档转化为html文件,命令如下:

 python historian.py -a bugreport.txt > battery.html

上面的historian.py脚本是Python写的,所以需要python环境,然后从github上下载这个脚本。

文件在github上面的scripts目录下面,需要下载到命令行所在的目录

 
19956127-ea72bb0c96e7ad00.png
 

注意:historian.py要与bugreport.txt在同一目录下

上面两条命令执行成功后,会在目录下发现两个文件

bugreport.txt和battery.html,这个时候我们用google浏览器打开html文件,可以看到如下信息:

 
19956127-5b110767b80bd144.png
 


各个参数的意义:

 
19956127-4aa036aaace70c98.png
 


上面的10,20代表的就是秒的意思,它是以一分钟为周期,到第60秒的时候变为0。横坐标就是一个时间范

围,咱们的例子中统计的数据是以重置为起点,获取bugreport内容时刻为终点。我们一共采集了多长时间的数据,图表下也有信息说明。

纵坐标:

纵坐标的数据就很麻烦了,数据量太多,一条一条来吧。

battery_level

电量,可以看出电量的变化。比如上图中的数据显示刚开始电量是100%,然后在第11秒-12秒中间的

某个时刻降到了99%。

 
19956127-87dc097650d605e3.png
 


plugged

充电状态,这一栏显示是否进行了充电,以及充电的时间范围。例如上图反映了我们在第22s插入了数

据线,然后一直持续了数据采集结束。

screen

屏幕是否点亮,这一点可以考虑到睡眠状态和点亮状态下电量的使用信息。

top

该栏显示当前时刻哪个app处于最上层,就是当前手机运行的app,用来判断某个app对手机电量的影响

,这样也能判断出该app的耗电量信息。该栏记录了应用在某一个时刻启动,以及运行的时间,这对我

们比对不同应用对性能的影响有很大的帮助。

wake_lock*

wake_lock该属性是记录wake_lock模块的工作时间。是否有停止的时候等

running

界面的状态,主要判断是否处于idle的状态。用来判断无操作状态下电量的消耗。

wake_lock_in

wake_lock有不同的组件,这个地方记录在某一个时刻,有哪些部件开始工作,以及工作的时间。

gps

gps是否开启

phone_in_call

是否进行通话

Sync

是否跟后台同步.

可以把鼠标停在某一项上面。可以看到何时sync同步启动的,持续时间Duration多久。

电池容量不会显示单一行为消耗的具体电量,这里只能显示使用电池的频率和时长,你可以看分时段

的剩余电量来了解具体消耗了多少电量。

 
19956127-03ed9268c7b5193a.png
 


Job

后台的工作,比如服务service的运行。从下面图中可以看到qihoo的AppStore和鲁大师都在运行后台

服务。

 
19956127-a5e15b483f4680ca.png
 


data_conn

数据连接方式的改变,上面的edge是说明采用的gprs的方式连接网络的。此数据可以看出手机是使用

2g,3g,4g还是wifi进行数据交换的。这一栏可以看出不同的连接方式对电量使用的影响。

status

电池状态信息,有充电,放电,未充电,已充满,未知等不同状态。

这一栏记录了电池状态的改变信息。

phone_signal_strength

手机信号状态的改变。

这一栏记录手机信号的强弱变化图,依次来判断手机信号对电量的影响。

health

电池健康状态的信息,这个信息一定程度上反映了这块电池使用了多长时间。

这一栏记录电池状态在何时发生改变,上面的图中电池状态一直处于good状态。
plug

充电方式,usb或者插座,以及显示连接的时间。

这一栏显示了不同的充电方式对电量使用的影响。

historian-V2最新的版本的方式:

将生成bugreport.txt文件在http://localhost:9999 中上传文件生成报告(前提在本地或者某服务器上搭好了

battery-historian项目环境)

 
19956127-358f64dc01ef8065.png
 
 
19956127-075f8a3242a77e13.png
 

其实在这里也可以看到两种版本分析模式:

 
19956127-7f6390cb8c5aabc8.png
 


至此使用方式就介绍完毕。

3、安卓的耗电模块补充与总结:

 
19956127-2e64cfb77b52b83e.png
 

如上,列出的一些常用的电量测试方法。综合各方法的优缺点,在定制个性化电量测试工具之前,目前采用的方法是Battery Historian。目前行业内,App耗电测试有很多种方案,如果仅仅测试出一个整体的电量值,对于定位问题是远远不够的。借助Battery Historian,可以查看自设备上次充满电以来各种汇总统计信息,并且可以选择一个App查看详细信息。所以QA的测试结果反馈从“这个版本App耗电量”高,变成“这个版本CPU占用高”“这个版本WiFi扫描异常”,可以帮助更快的定位到问题原因及解决问题。
参考:https://www.cnblogs.com/gnfx/p/8608343.html
https://blog.csdn.net/momo_ibeike/article/details/79500157

阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

原文地址:https://www.cnblogs.com/Android-Alvin/p/11958719.html