如何通過(guò)Battery Historian分析Android APP耗電情況
一、電量統(tǒng)計(jì)模塊概述
耗電信息在設(shè)置 -> 電量中能夠非常直觀的看到。注意,Android 所有功耗統(tǒng)計(jì)都是通過(guò)代碼估算,沒(méi)有集成電路參與匯報(bào)。準(zhǔn)確度取決于廠商 ROM 所提供的power_profile.xml文件。由于不同廠商power_profile.xml準(zhǔn)確度及源碼有差異,因此不同手機(jī)、不同版本的數(shù)據(jù)可能有較大差異。
power_profile.xml直接影響統(tǒng)計(jì)的準(zhǔn)確度,并且此文件無(wú)法通過(guò)應(yīng)用修改。再次強(qiáng)調(diào),Android 耗電估算沒(méi)有硬件的參與,全靠代碼估算。
power_profile.xml文件位于源碼下的/framework/base/core/res/res/xml/power_profile.xml,部分內(nèi)容展示如下:
<item name="radio.scanning">0.1</item> <!-- cellular radio scanning for signal, ~10mA -->
<item name="gps.on">0.1</item> <!-- ~50mA -->
<!-- Current consumed by the radio at different signal strengths, when paging -->
<array name="radio.on"> <!-- Strength 0 to BINS-1 -->
<value>0.2</value> <!-- ~2mA -->
<value>0.1</value> <!-- ~1mA -->
</array>
</array>
<!-- Different CPU speeds as reported in
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state -->
<array name="cpu.speeds">
<value>400000</value> <!-- 400 MHz CPU speed -->
</array>
<!-- Current when CPU is idle -->
<item name="cpu.idle">0.1</item>
<!-- Current at each CPU speed, as per 'cpu.speeds' -->
<array name="cpu.active">
<value>0.1</value> <!-- ~100mA -->
</array>
<array name="wifi.batchedscan"> <!-- mA -->
<value>.0002</value> <!-- 1-8/hr -->
<value>.002</value> <!-- 9-64/hr -->
<value>.02</value> <!-- 65-512/hr -->
<value>.2</value> <!-- 513-4,096/hr -->
<value>2</value> <!-- 4097-/hr -->
</array>
這就是在硬件層面統(tǒng)計(jì)時(shí),直接參與運(yùn)算的參數(shù)。無(wú)論是軟件耗電統(tǒng)計(jì)還是硬件耗電統(tǒng)計(jì),都通過(guò)BatteryStatsHelper來(lái)進(jìn)行匯總。BatteryStatsHelper位于/framework/base/core/java/com/andorid/internal/os/BatteryStatsHelper.java下。
1.1、軟件耗電統(tǒng)計(jì)
在BatteryStatsHelper.java中,有這么一個(gè)方法:
private void processAppUsage(SparseArray<UserHandle> asUsers) {
final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null);
mStatsPeriod = mTypeBatteryRealtime;
BatterySipper osSipper = null;
final SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
final Uid u = uidStats.valueAt(iu);
final BatterySipper app = new BatterySipper(BatterySipper.DrainType.APP, u, 0);
mCpuPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mWakelockPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mMobileRadioPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mWifiPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mBluetoothPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mSensorPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mCameraPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mFlashlightPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
final double totalPower = app.sumPower();
if (DEBUG && totalPower != 0) {
Log.d(TAG, String.format("UID %d: total power=%s", u.getUid(),
makemAh(totalPower)));
}
}
... // code
}
processAppUsage()方法中,一個(gè)應(yīng)用的總功耗在這里體現(xiàn)出來(lái)了:
- cpu
- Wakelock(保持喚醒鎖)
- 無(wú)線電(2G/3G/4G)
- WIFI
- 藍(lán)牙
- 傳感器
- 相機(jī)
- 閃光燈
這些數(shù)據(jù),將決定著你的應(yīng)用在耗電排行榜中的位置,以及是否給予用戶警告高耗電。這些警告對(duì)于應(yīng)用來(lái)說(shuō)可能是致命的,用戶可能因此而卸載應(yīng)用。
應(yīng)用總功耗是上述八個(gè)統(tǒng)計(jì)值的和。這八個(gè)統(tǒng)計(jì)器同繼承自PowerCalculator.java
具體來(lái)說(shuō),這八個(gè)耗電計(jì)算器的算法分別如下:

耗電統(tǒng)計(jì)概述就如上所述。總的來(lái)說(shuō)并不復(fù)雜,通過(guò)聚合八種不同方式的消耗,來(lái)得出總的耗電量,并給予用戶展示。
二、battery-historian
2.1、概述
Battery Historian ,是谷歌出品的耗電分析器。通過(guò) Battery Historian,可將導(dǎo)出的 bugreport 文件可視化。在第一代的 Battery Historian 中,google 使用了 python 作為數(shù)據(jù)解析工具。拿到 bugreport 文件后,通過(guò)終端執(zhí)行 python 來(lái)生成可視化的 html 文件。這種方法使用起來(lái)較為麻煩,而且無(wú)法部署到服務(wù)器。因此在第二代 Battery Historian,google 選擇了使用 docker 容器?,F(xiàn)在完全不推薦使用第一代 Battery Historian,已經(jīng)許久沒(méi)有維護(hù)了,而且功能過(guò)于簡(jiǎn)陋。
需要注意的是 battery-historian 在使用時(shí)候不能在充電,同時(shí)確保設(shè)備運(yùn)行的 Android 版本是 5.0 及以上。
通過(guò)上面的描述,對(duì)battery-historian 的功能有個(gè)大概的了解,下面進(jìn)入到實(shí)戰(zhàn)。
2.2、獲取bugreports
battery-historian 雖然功能強(qiáng)大,但是也是需要先提供數(shù)據(jù)的,其數(shù)據(jù)的獲取需要我們手動(dòng)操作。下面介紹如何獲取bugreports。
1.電腦連接上手機(jī),斷開(kāi)adb服務(wù),adb作為一種連接的方式,有可能被其他的程序占用,所以我們做電量記錄時(shí)要避免打開(kāi)很多可能沖突的東西
adb kill-server
2. 重啟adb服務(wù)
adb devices || adb start-server
3. Android也不記錄特定于應(yīng)用程序的用戶空間wakelock轉(zhuǎn)換的時(shí)間戳。如果您希望Historian在時(shí)間線上顯示關(guān)于每個(gè)單獨(dú)喚醒鎖的詳細(xì)信息,則應(yīng)在開(kāi)始實(shí)驗(yàn)之前使用以下命令啟用完整喚醒鎖報(bào)告:
adb shell dumpsys batterystats --enable full-wake-history
4. 采集報(bào)告前將battery統(tǒng)計(jì)狀態(tài)重置,重置命令結(jié)束后斷開(kāi)usb,測(cè)試結(jié)束后用獲取報(bào)告命令導(dǎo)出統(tǒng)計(jì)文件包
adb shell dumpsys batterystats --reset
5. 導(dǎo)出電量,對(duì)于 7.0 系統(tǒng)以上的設(shè)備運(yùn)用:
adb bugreport bugreport.zip
adb bugreport > $HOME/Documents/bugreport.zip // 指定到對(duì)應(yīng)目錄下,具體分機(jī)型,可能會(huì)有些不一樣
6.0 或更低版本:
adb bugreport > bugreport.txt
2.3、數(shù)據(jù)分析
獲取到數(shù)據(jù)后,接下去就是對(duì)數(shù)據(jù)進(jìn)行分析了。
如圖所示Battery Historian圖表的一個(gè)例子:

其中標(biāo)號(hào)的意義是:
- 標(biāo)號(hào)1:從下拉列表中添加其他指標(biāo);
- 標(biāo)號(hào)2:將鼠標(biāo)懸停在信息圖標(biāo)上可以查看有關(guān)每個(gè)指標(biāo)的詳細(xì)信息,包括圖表中使用的不同顏色代表意義的介紹;
- 標(biāo)號(hào)3:將鼠標(biāo)懸停在某個(gè)條目上可以查看該指標(biāo)的更多詳細(xì)信息,以及時(shí)間線上特定點(diǎn)的耗電量信息;
這是整個(gè)手機(jī)狀態(tài)圖,包括手機(jī)電量,CPU 使用時(shí)長(zhǎng),wifi 信號(hào)的強(qiáng)度,手機(jī)溫度變化等等,都在上面詳細(xì)的用圖表展示出來(lái)了。
Battery Historian除了能夠提供宏觀的系統(tǒng)層面的信息,還能夠提供針對(duì)指定App的可視化數(shù)據(jù)和表格信息,這表格主要信息包括:
- Device estimated power use等基本信息
- Networks Information:app網(wǎng)絡(luò)信息
- Wakelocks:?jiǎn)拘焰i信息,一般和業(yè)務(wù)強(qiáng)相關(guān)
- Services:服務(wù)信息,查看App開(kāi)啟的services信息
- Process info:進(jìn)程信息
Battery Historian圖表下為數(shù)據(jù)分析,包括三個(gè)Tab,如下圖所示,可以查看App更多信息:

其中,標(biāo)號(hào)所代表的意義是:
- 標(biāo)號(hào)1:System Stats 分組包含系統(tǒng)級(jí)別的數(shù)據(jù),比如屏幕亮度等。這一欄顯示了系統(tǒng)發(fā)生的總體情況,可以用來(lái)測(cè)試是否存在外部影響事件;
- 標(biāo)號(hào)2:App Stats分組包含針對(duì)指定APP的詳細(xì)信息;
- 標(biāo)號(hào)3:可以根據(jù)不同的分類標(biāo)準(zhǔn)對(duì)APP進(jìn)行排序;
- 標(biāo)號(hào)4:在下拉列表中選擇指定的APP后可在App Stats中查看具體信息,App Stats所展示的都是所選定App產(chǎn)生的數(shù)據(jù),不會(huì)受到外部因素的影響;
下面看看具體某個(gè)手機(jī)的數(shù)據(jù),比如百度APP應(yīng)用的數(shù)據(jù),在右邊選擇對(duì)應(yīng)的 APP,左邊就會(huì)展示當(dāng)前 APP 的電量,網(wǎng)絡(luò)等情況。

2.4、bugreport 文件分析
前面是通過(guò)Battery History 對(duì)bugreport 的文件進(jìn)行了分析,那如果我們想自己分析呢?因此,在這里有必要了解下bugreport 的文件內(nèi)容。
電量統(tǒng)計(jì)信息起始,包含 reset 時(shí)間,進(jìn)程信息等

下面是距離上次充電后的數(shù)據(jù)統(tǒng)計(jì):

每個(gè) APP 電量使用情況,通過(guò) Uid 來(lái)標(biāo)識(shí)APP

可以通過(guò)關(guān)鍵字下面的關(guān)鍵字來(lái)尋找相關(guān)信息。
DUMP OF SERVICE
通過(guò)該關(guān)鍵字可以查到 wifi, 網(wǎng)絡(luò), activities 等等的信息。
以上就是如何通過(guò)Battery Historian分析Android APP耗電情況的詳細(xì)內(nèi)容,更多關(guān)于Battery Historian Android APP耗電情況的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android編程之電池電量信息更新的方法(基于BatteryService實(shí)現(xiàn))
- Android優(yōu)化之電量?jī)?yōu)化的實(shí)現(xiàn)
- Android4.4開(kāi)發(fā)之電池低電量告警提示原理與實(shí)現(xiàn)方法分析
- Android電池電量跳變
- Android省電的秘密之JobScheduler
- Android實(shí)現(xiàn)顯示電量的控件代碼
- Android開(kāi)發(fā)教程之電源管理詳解
- Android編程實(shí)現(xiàn)檢測(cè)當(dāng)前電源狀態(tài)的方法
- android電源信息查看(電量、溫度、電壓)實(shí)例代碼
相關(guān)文章
android中DownloadManager實(shí)現(xiàn)版本更新,監(jiān)聽(tīng)下載進(jìn)度實(shí)例
本篇文章主要介紹了android中DownloadManager實(shí)現(xiàn)版本更新,監(jiān)聽(tīng)下載進(jìn)度實(shí)例。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
anndroid使用ViewPager實(shí)現(xiàn)三個(gè)fragment切換
這篇文章主要介紹了anndroid使用ViewPager實(shí)現(xiàn)三個(gè)fragment切換,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
Android垃圾回收機(jī)制及程序優(yōu)化System.gc
這篇文章主要介紹了Android垃圾回收機(jī)制及程序優(yōu)化System.gc的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android 自定義 View 中使用 Spannable的實(shí)例詳解
這篇文章主要介紹了Android 自定義 View 中使用 Spannable的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Android數(shù)據(jù)庫(kù)LitePal的基本用法詳解
這篇文章主要介紹了Android數(shù)據(jù)庫(kù)LitePal的基本用法詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Android Retrofit 中文亂碼問(wèn)題的解決辦法
這篇文章主要介紹了Android Retrofit 中文亂碼問(wèn)題的解決辦法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家遇到這種問(wèn)題及時(shí)的解決,需要的朋友可以參考下2017-10-10
android編程實(shí)現(xiàn)對(duì)話框的封裝實(shí)例
這篇文章主要介紹了android編程實(shí)現(xiàn)對(duì)話框的封裝,以實(shí)例形式分析了Android針對(duì)對(duì)話框的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11

