本文主要分享Android應用耗電量的統計分析方法和工具。html
衆所周知,Android系統內置了應用的耗電量統計分析功能,可是並無提供相應的API和文檔,只是能夠查看耗電量排行榜前10的應用的耗電百分比。此外,隨着Android系統版本的迭代,各個版本耗電量統計的方式略有不一樣,但慶幸的是其統計模型並無什麼大變化。本文在前人的研究基礎上總結Android平臺的耗電量統計相關的計算方法和輔助工具。java
(1)Android系統是如何進行應用的耗電量統計的?python
若是想了解Android系統是如何對應用進行耗電量統計計算的話建議先閱讀:Android耗電統計算法這篇文章,做者是小米的MIUI系統工程師Gityuan(若是你想了解Android系統中常見模塊的實現細節的話,很是推薦閱讀這位開發者的博客,他的博客文章的質量都很是高),此文從Android 6.0系統源碼的角度詳細分析了應用的耗電量的計算方法。閱讀上文可知,耗電量計算包括軟件耗電量計算和硬件耗電量計算,而且有各自的計算方法。linux
下圖是軟件的耗電量統計項以及它的功耗計算公式:android
下圖是硬件的功耗計算公式:git
其餘文章推薦:
1.深刻淺出Android App耗電量統計
該文是耗電量統計方面最先的文章,分析的是Android 4.3系統源碼中的應用耗電量統計
2.Android應用的耗電量統計
該文是在上面的文章2的基礎上作的分析,分析的是Android 5.1系統源碼
3.Android性能專項測試之耗電量統計API
該文是以Android 6.0系統源碼來分析應用耗電量統計github
下面是從源碼的分析得出的對於電量統計的通俗介紹:面試
耗電量計算的方法頗有趣,有點象在超市購物:有一張「價格表」,記錄每種硬件1秒鐘耗多少電。有一張「購物清單」,記錄apk使用了哪幾種硬件,每種硬件用了多長時間。假設某個應用累計使用了60秒的cpu,cpu1秒鐘耗1mAh,那這個應用就消耗了60mAh的電,實際的算法比這個例子複雜不少。算法
從這裏能夠看出,Android自帶的耗電量統計的準確性,受兩個大方面的因素影響:docker
一是那張「價格表」,由PowerProfile
類提供,它用於獲取各個組件的電流數值,而power_profile.xml
是一個可配置的功耗數據文件。手機的硬件是各不相同的,因此每一款手機都會有一張本身的「價格表」。這張表的準確性由手機廠商負責,因此,儘可能用大廠的機子,而且只使用該廠商提供的Android系統。
二是那張「購物清單」,這是Android的BatteryStatsService
類提供的。前面那篇文章提到過,BatteryStatsHelper
類使用AIDL調用BatteryStatsService
類的getStatisticsStream
方法獲取相關數據。
下面是其中幾個模塊的耗電量計算方式
WIFI模塊的耗電量和應用流進流出的流量總量、wifi掃描時間、wifi模塊運行時間有關
Sensor模塊的耗電量與sensor的使用時間成正比
從上面幾篇文章中能夠看出,各個Android版本的系統源碼中耗電量統計的方式雖略有不一樣,可是大體的統計模型是不變的,並且統計的方式愈來愈科學可靠。Google官方對耗電量的統計給出的解釋都是不能表明真實數據,只能做爲參考值,由於受power_profile.xml的干擾太大,若是手機廠商沒有嚴格設置這個文件,那可想而知出來的值多是不合理的。
(2)普通的應用開發者能夠怎麼統計應用的耗電量?
因爲權限的限制,普通的應用開發者並不太容易統計應用的耗電量。前面的推薦文章3中也提到過獲取應用耗電量的權限控制,內容以下:Android4.4之前的版本,未對耗電量統計的代碼作權限限制,只須要使用java反射等手段,就能夠調用相關的內部類和隱藏接口。自Android4.4開始,Android嚴格限制了權限,普通應用即便在AndroidManifest.xml中申明使用android.permission.BATTERY_STATS
,也獲取不到相關的統計數據。
統計應用耗電量的工具:
1.GT的Powerstat (騰訊開發的應用耗電量統計工具)
項目地址:http://gt.tencent.com/
Powerstat的功能很強大,可是要求手機是root過的。
Powerstat用戶手冊中有說明:Android 電量測試工具 Powerstat V1.x 版本支持 Android4.1~4.4的系統(4.4及以上系統上須要系統簽名,在已獲取root權限的狀況下,可將apk包置於/system/priv-app/
目錄下,做爲系統應用運行)。工具的 V1.x2 版本在V1.x 版本的基礎上進行開發,細分耗電項,增長定時自動保存功能,適配Android5.0。一樣,在 Android4.4 及以上系統也須要root權限才能安裝使用。
Powerstat的應用耗電量計算方法基本上和系統的應用耗電量計算方法是同樣的,它是經過各類方式包括反射的方法來獲取應用在一段時間內的數據(例如佔用的CPU時間、流進流出的數據量等),而後利用系統的統計類BatteryStatsHelper
作些修改來計算應用的耗電量。比較有意思的是其中有個用來計算應用的屏幕耗電量的類。爲啥屏幕耗電量計算這麼麻煩呢?由於在測試的過程當中測試應用並不是一直在前臺,爲了計算的應用耗電量準確些,須要將屏幕的總耗電量按照應用在前臺的時間進行分配。計算方法就是根據屏幕總耗電量和全部應用的forground cpu time總和來計算每一個forground cpu time消耗的電量,並根據每一個應用佔用的forground cpu time來計算其對應的屏幕耗電量。這個就相似統計一個應用佔用的內存時咱們經常關注PSS,而不是USS的道理是同樣的,共享庫佔用的內存要均攤到使用了它的每一個應用中。
2.Battery Historian (Google官方出品)
項目地址:https://github.com/google/battery-historian
Battery Historian是Google提供的針對Android 5.0及以上系統使用的分析電量相關信息的工具。
Battery Historian is a tool to inspect battery related information and events on an Android device running Android 5.0 Lollipop (API level 21) and later, while the device was not plugged in. It allows application developers to visualize system and application level events on a timeline with panning and zooming functionality, easily see various aggregated statistics since the device was last fully charged, and select an application and inspect the metrics that impact battery specific to the chosen application. It also allows an A/B comparison of two bugreports, highlighting differences in key battery related metrics.
目前BatteryHistorian工具備兩個版本:
2.1 Battery Historian 1.x
第一個版本是python語言寫的,只有一個Python腳本文件 historian.py,這個文件能夠從初版本的最後一次提交記錄中下載(https://github.com/google/battery-historian/tree/b711e0a8345147f449fd017e21913a8a6b8bd638) ,初版本的使用步驟以下:
$ adb shell dumpsys batterystats > xxx.txt //獲得整個設備的電量消耗信息 $ adb shell dumpsys batterystats > com.package.name > xxx.txt //獲得指定app相關的電量消耗信息
獲得了原始的電量消耗數據以後,咱們須要經過 historian.py 腳本把數據信息轉換成可讀性更好的html文件
$ python historian.py xxx.txt > xxx.html
打開這個轉換事後的html文件,能夠看到相似TraceView生成的列表數據,其中的數據信息量很大
舊版本的詳細使用流程以及分析過程能夠參考Batterystats & Battery Historian Walkthrough 和 Battery Historian Charts,其中有些術語可能不太好理解,這裏有個簡略的中文的解釋版本
下圖很重要,它對不一樣類別的電量消耗進行了解釋
2.2 Battery Historian 2.x
第二個版本是go語言寫的,代碼不少,功能也更加完善,可是環境配置也更加複雜!
首先,咱們須要將Battery Historian工具在本地跑起來,要跑起來能夠選擇使用docker,也能夠選擇編譯源碼。
(1)若是是使用Mac或Linux平臺的話,推薦直接經過docker運行Battery Historian來完成
docker -- run -p <port>:9999 gcr.io/android-battery-historian:2.1 --port 9999
以後在瀏覽器中輸入 http://localhost: 就能夠看到效果,而後上傳bugreport文件進行分析了。
(2)若是是使用Windows平臺的話,也可使用docker,可是機子要在BIOS中開啓虛擬化,因此這裏我選擇源碼編譯方式,主要流程:
1.首先下載配置Java環境 (要配置PATH)
2.接着下載配置Git環境 (要配置PATH)
3.接着下載配置Python 2.7環境 (要配置PATH)
4.接着下載配置Go環境 (要配置PATH和GOPATH以及GOBIN)
5.前面的配置其實很快就能完成,接下來就是下載Battery Historian的源碼來進行編譯了
$ go get -d -u github.com/google/battery-historian/…
下載完成以後,代碼會下載到配置的GOPATH中,能夠去檢查下
$ cd $GOPATH/src/github.com/google/battery-historian
切換到那個目錄,而後執行setup.go開始編譯源碼
go run setup.go
若是遇到下面的問題的話別擔憂,按照提示將對應url的文件下載下來放在要求的目錄便可
上面的步驟都完成以後就能夠啓動Battery Historian了,默認端口是9999
$ go run cmd/battery-historian/battery-historian.go
待控制檯輸出listening on port:9999
的時候,能夠打開瀏覽器輸入 http://localhost:9999 就能夠看到
其次,這個版本的輸入是bugreport文件,根據系統版本不一樣它的獲取方式略有差異:
若是是Android 7.0及以上版本的話能夠經過 adb bugreport bugreport.zip
來獲取bugreport
若是是Android 6.0及如下版本的話能夠經過 adb bugreport > bugreport.txt
來獲取bugreport
獲取到bugreport文件以後,咱們就能夠將其上傳到Battery Historian上進行分析,下面是它的輸出結果
在頁面的下方咱們能夠查看這段時間內系統的狀態system stats,也能夠選擇某個應用查看應用的狀態app stats
其中咱們能夠看到Device estimated power use
中顯示了估算的應用耗電量值爲 0.18%
Battery Historian還有個比較功能,在首頁選擇 Switch to Bugreport Comparisor,而後就能夠上傳兩個不一樣的bugreport文件,submit以後就能夠看到它們的對比結果了,這個功能用來分析同一個應用的兩個不一樣版本先後的耗電量很是有用。
須要注意的是,通常開始統計數據以前須要使用下面的命令將之前的累積數據清空
adb shell dumpsys batterystats --reset
By default, Android does not record timestamps for application-specific userspace wakelock transitions even though aggregate statistics are maintained on a running basis. If you want Historian to display detailed information about each individual wakelock on the timeline, you should enable full wakelock reporting using the following command before starting your experiment:
adb shell dumpsys batterystats --enable full-wake-history
關於bugreport相關的知識推薦閱讀Android adb bugreport工具分析和使用這篇文章,做者簡單地從源碼角度分析了adb bugreport
命令的運行原理,結論是bugreport實際上是啓動了dumpstate服務來輸出數據,其中數據來源包括:
1.系統屬性
2./proc和/sys節點文件
3.執行shell命令得到相關輸出
4.logcat輸出
5.Android Framework Services信息基本使用dumpsys命令經過binder調用服務中的dump函數得到信息
下面是其餘的幾篇關於battery-historian使用的文章可供參考
(1)Android性能專項測試之battery-historian使用
(2)Android性能專項測試之Batterystats
(3)Battery Historian 2.0 for windows環境搭建
3.關於電量方面的Android性能優化
電量方面的性能優化能夠參考 性能優化典範中的Android性能優化之電量篇
主要有如下兩點:
(1)爲了減小電量的消耗,在蜂窩移動網絡下,最好作到批量執行網絡請求,儘可能避免頻繁的間隔網絡請求
(2)使用Job Scheduler,應用須要作的事情就是判斷哪些任務是不緊急的,能夠交給Job Scheduler來處理,Job Scheduler集中處理收到的任務,選擇合適的時間,合適的網絡,再一塊兒執行
Hujiawei is a mobile developer Guangdong, China https://hujiaweibujidao.github.io/本博客全部文章均爲原創,請勿隨意轉載,如需轉載請聯繫我 (hujiawei090807 AT gmail.com)我在小專欄有個移動開發技術專欄,不按期分享移動開發的核心技術,總結移動開發的實戰經驗
全部文章皆爲原創,內容製做精良,保證乾貨滿滿,歡迎訂閱 (https://xiaozhuanlan.com/u/javayhu)
>>> 我最近在Android面試指南小專欄裏面寫了一篇稿子 [Android面試——算法面試心得] ,歡迎閱讀!<<<