[Android]電量優化之app演算法

大搜車-自娛發表於2014-07-23
針對Android的電量優化,應該是很多開發者最關心的幾大問題之一。
最近我正在看相關的資料,希望跟大家一起探討學習。

關於電量,我們最需要處理的問題就是兩個方向:
(1)第三方APP和系統本身是如何獲取電量值並展示的?我們能否針對他們的演算法做適度優化?或者規避部分統計?
(2)其他程式碼級別優化。從業務邏輯出手,架構上適度調整的手段有哪些?

就上面2個問題,我們開始展開討論:
(1)APP獲取電量演算法。
經過檢視原始碼,以及各種資料。最後我們看到app計算電量的演算法如下:

在主Activity裡面 info.getBatteryStats() 就搞定了。 首先 load(),如果load失敗,走CPU時間計算,通過getAppListCpuTime這樣函式。 1
CPU的時間計算,有3個核心步驟:
1 ActivityManager遍歷runningApp程式,獲取對應pid
2 getAppProcessTime(pid)通過讀取/proc/pid/stat檔案,拿取APP在CPU的執行時間。
3 重新為BatterySipper附值:+time;
2

獲取APP消耗 processAppUsage();也分三步走:
1 通過PowerProfile 獲取cpu的速度層次(speedsteps),方便後面使用
2 根據不同CPU的速度等級,計算cpu在某個速度下的電量,mA毫安
3

mPowerProfile.getAveragePower(PowerProfile.POWERCPUACTIVE,p)
很多地方都用刀這個API獲取power。
那它究竟做了些什麼呢?
檢視系統原始碼可以知道:
實際上這句話是獲取1個叫PowerMap的資料結果,獲得電量。而PoweMap的賦值,是來源於com.android.internal.R.xml.powerprofile 的檔案。
關於該檔案的獲取 android-版本號/core/res/res/xml/powerprofile.xml

計算各種耗電量的詳細演算法是:
(1)計算CPU
BatteryStateImpl.getUidStats()獲取資料來源
遍歷資料來源,得到ProcessState
通過ProcessState拿到以下幾個指標
userTime
systemTime
foregroundTime
CpuFgTime(cpuFgTime+= foregroundTime10;)
cpuTime (cpuTime+=tmpCpuTime)
tmpCpuTime=(userTime + systemTime)10

power +=processPower
4

(2)計算wake lock
wakelock,只關心partial的型別
同樣地,通過uid獲取wakelock的資訊 u.getWakelockStats()

遍歷這個map,獲取wakeTime次數
wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);

計算總耗時 wakelockTime += timer.getTotalTimeLocked(uSecTime,which);
計算總電量 poewer+=
6
(3)資料通訊的消耗
7
(4)wifi執行消耗
8
(5)感測器等等

processMiscUsage()
9
以wifi為例,是所以wifi的電量(wifi使用電量+appwifi使用電量)
addwifiusage()為例子:
long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; //獲取wifi總時間
long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; //獲取wifi執行時間
runningTimeMs -= mAppWifiRunning;//這裡計算的是非app使用wifi的量(時間)

double wifiPower = (onTimeMs * 0 * mPowerProfile.getAveragePower(PowerProfile.POWERWIFION) + runningTimeMs
* mPowerProfile.getAveragePower(PowerProfile.POWERWIFION)) / 1000;//時間*電量==毫安時

為了方便各位學習,我把Demo也上傳上來,希望對大家閱讀有所幫助。

相關文章