深入浅出Android App耗电量统计
原文出處:http://www.cnblogs.com/hyddd/p/4402621.html
在Android統計App耗電量比較麻煩,直至Android 4.4,它仍沒公開“電量統計”API或文檔……額,是的,僅沒有公開,并不是沒有。平時在手機“設置- 電量”看到的數據
?? ?
?就是系統調用內部API的統計結果。
基礎概念
手機由眾多“部件”組成,所謂“部件”是指:CPU,WIFI,GPS....所以,Android?App消耗總電量為 App運行過程中,涉及各部件的消耗電量的總和。假設運行App導致CPU運行,時間:t,CPU單位時間消耗電量:w,則App的CPU耗電量為:W = w*t,而有物理公式 W = U*I*t(U:電壓值,I:電流值),在手機中,一般U恒定不變,所以,可以單獨通過 Q(電容量,單位: mAh)= I * t 表示電量。 ? 系統源碼分析
????核心源碼:/packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageSummary.java
????核心類:
- BatteryStatsImpl:提供App各部件運行時間
- PowerProfile:提供部件電流數值
????問題:
- Android怎樣存儲與讀取App耗電量信息(即:BatteryStatsImpl數據怎么來的?)
- Android怎么存儲部件電流數值(即:PowerProfile數據怎么來的?)
- Android具體耗電量計算方法
??????? (1)先看下PowerUsageSummary.java如何獲取BatteryStatsImpl?
??????? ?
?????? ?
?????? ?
??????? 可見 BatteryStatsImpl 通過 系統服務“batteryinfo”獲得。
??????? (2)系統服務“batteryinfo”是什么玩意呢?(見:BatteryStatsService.java)
?????? ?
??????? 系統服務“batteryinfo”其實就是BatteryStatsService,而BatteryStatsService“唯一的”構造函數提供了一個很重要的信息:filename!
??????? (3)BatteryStatsService在哪里創建?filename是什么?(見:ActivityManagerService.java)
?????? ?
??????? filename文件是:/data/system/batterystats.bin,關于batterystats.bin,之前民間很多文章說它用作電池校正,但Android工程師Dianne Hackborn在google+上明確:
?????? ?
??????? betterystats.bin文件僅僅是一個記錄不同app使用電量的一個文件。
??????? (4)再看看 BatteryStatsImpl(String filename) 構造函數(見:BatteryStatsImpl.java)
?????? ?
??????? 這里只做了些基本的初始化。真正載入betterystats.bin數據是在(ActivityManagerService.java)mBatteryStatsService.getActiveStatistics().readLocked();
?????? ?
?????? ?
??????? 至此,Android怎樣存儲與讀取App耗電量信息分析結束。
??????? 總結:
- ActivityManagerService 創建并初始化 BatteryStatsService,并傳入耗電量記錄文件batterystats.bin
- BatteryStatsService 在內部創建 BatteryStatsImpl 實例,并傳入耗電量記錄文件batterystats.bin
- ActivityManagerService 執行 mBatteryStatsService.getActiveStatistics().readLocked();導致 BatteryStatsService 的 BatteryStatsImpl 加載batterystats.bin數據
- 在PowerUsageSummary計算App耗電量時,PowerUsageSummary從BatteryStatsService 中獲取BatteryStatsImpl 實例,從而獲得App的相關數據
????2. Android怎么存儲部件電流數值
??????? (1)比較簡單,見?PowerProfile.java
?????? ?
??????? PowerProfile讀取資源 com.android.internal.R.xml.power_profile,并把數據加載到sPowerMap。
??????? (2)com.android.internal.R.xml.power_profile在哪里?
??????? 在官方文檔《Power Profiles for Android》明確了power_profile.xml位置:device///frameworks/base/core/res/res/xml/power_profile.xml。
??????? 下面是一個samsung的power_profile.xml:
?????? ?
??????? 字段含義見《Power Profiles for Android》。
??????? (3)每個OEM廠商有自己獨立的power_profile.xml配置
??????? 官方文檔表明:OEM廠商應該有自己的power_profile.xml,因為部件(如:cpu, wifi…)耗電量應與具體硬件相關,這個只有OEM廠商清楚……
?????? ?
??????? (4)PowerProfile關鍵API:
- public double getAveragePower(String type):返回type的電流值(mA),type表示power_profile.xml中的某關鍵字(如:gps.on)
- public double getAveragePower(String type, int level) :返回type的電流值(mA),level表示xml中array的第幾個value
??????? 至此,Android怎么存儲部件電流數值分析結束。
??????? 總結:
??????? (1)Android部件電流信息存于:power_profile.xml
??????? (2)每個OEM廠商有私有power_profile.xml
??????? (2)PowerProfile讀取power_profile.xml,并提供API訪問部件電流數值。
?
????3. Android具體耗電量計算方法
??????? App耗電量統計:processAppUsage()??
??????? 硬件耗電量統計:processMiscUsage()
?
????????processAppUsage()分析
????????????【1】processAppUsage耗電量統計的 時間段 是?
?????????? ?
?????????? ?
??????????? 關于統計的 時間段,BatteryStats有4個選項:
?????????? ?
??????????? 可見,processAppUsage 是 上一次拔掉設備后 ~ 至今 的App耗電量統計。
??????????
????????????【2】processAppUsage 的統計對象真的是App?
?????????? ?
??????????? 具體的 統計流程 都在for循環里,額……所以processAppUsage真實統計粒度是Uid。
??????????? Uid與App關系:2個App簽名和sharedUserId相同,則在運行時,他們擁有相同Uid。就是說processAppUsage統計的可能是多個App的耗電量數據,對于普通App,出現這種情況的幾率較少,而對于Android系統應用則較為常見。
?
????????????【3】耗電量計算公式 - 部分1:計算Uid屬下每個Process的耗電量數據,并求和。
??????????? Uid_Power1 = (Process1_Power + … + ProcessN_Power);
??????????? Process_Power = (CPUSpeed_Time * POWER_CPU_ACTIVE);
????????????
?
????????????【4】耗電量計算公式 - 部分2:計算Uid的wake lock耗電量
??????????? 這里,Android只計算了partial wake lock的耗電量。
?????????? ?Uid_Power2 = PartialWakeLock_Time * POWER_CPU_WAKE
????????????
?
????????????【5】耗電量計算公式 - 部分3:計算Uid的數據流量(data traffic)耗電量
??????????? Uid_Power3 = ( tcpBytesReceived + tcpBytesSent ) * averageCostPerByte
?????????? ?
?????????? ?
?
????????????【6】耗電量計算公式 - 部分4:計算Uid WIFI耗電量。
?????????? ?Uid_Power4 = wifiRunningTimeMs * POWER_WIFI_ON
?????????? ?
?
????????????【7】耗電量計算公式 - 部分5:計算Uid其他傳感器耗電量。
?????????? ?Uid_Power5 = (Sensor1_Power + … + SensorN_Power)
?????????? ?Sensor_Power = Sensor_Time * Power_Sensor
?
??????????? 至此,App耗電量計算方法分析結束。硬件耗電量統計(processMiscUsage())亦類似。
????????????總結App耗電量計算公式:
??????????????? Uid_Power(App耗電量,單位:mAh) = Uid_Power1 + Uid_Power2 + Uid_Power3 + Uid_Power4 + Uid_Power5
??????????????????? Uid_Power1 = (Process1_Power + … + ProcessN_Power);
??????????????????????? - Process_Power = (CPUSpeed_Time * POWER_CPU_ACTIVE);
??????????????????? Uid_Power2 = PartialWakeLock_Time * POWER_CPU_WAKE??????????????
??????????????????? Uid_Power3 = ( tcpBytesReceived + tcpBytesSent ) * averageCostPerByte
??????????????????? Uid_Power4 = wifiRunningTimeMs * POWER_WIFI_ON
??????????????????? Uid_Power5 = (Sensor1_Power + … + SensorN_Power)
??????????????????????? - Sensor_Power = Sensor_Time * Power_Sensor
? ??????????? 說這么多,來一發……不,來一個統計耗電量的App吧,其實,之前已有人把這段Android系統代碼摳出來,做了一個App,可以到?這里下載。? ? ? ? ? ? 有一個好消息是:android5.0后,獲取電量數據不用這么痛苦了,dumpsys?batterystats數據中。包含:Estimated power use (mAh):,下面就是每個uid的耗電量,只要把app下所有uid耗電量加起來即可!
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的深入浅出Android App耗电量统计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RxJava 在Android中的应用(
- 下一篇: Android动态加载技术