電量統(tǒng)計(jì)原理以及電量優(yōu)化實(shí)踐

"
Free apps like Free Chess and Angry Birds spend under 25-35 percent of their energy on game play, but over 65-75 percent on user tracking, uploading user information and downloading ads.
"
android電量統(tǒng)計(jì)的原理可以參看這篇文章:
http://duanqz.github.io/2015-07-21-batterystats-part1

大致原理摘錄如下:
電量記錄
1. Android在進(jìn)行電量統(tǒng)計(jì)時(shí),并不是采用直接記錄電流消耗量的方式臭埋,而是跟蹤硬件模塊在不同狀態(tài)下的使用時(shí)間,收集一些可用信息搀庶,用來近似的計(jì)算出電池消耗量蕉汪。

舉一個(gè)例子盟蚣,假定某個(gè)APK的使用了GPS刺覆,使用時(shí)間用 t 表示绽族。GPS模塊單位時(shí)間的耗電量用 w 表示姨涡,那么,這個(gè)APK使用GPS的耗電量就可以按照如下方式計(jì)算:
耗電量 = 單位時(shí)間耗電量(w) × 使用時(shí)間(t)
frameworks.jar里的frameworks/base/core/res/res/xml/power_profile.xml這個(gè)文件吧慢,記錄著各個(gè)模塊單位時(shí)間的耗電量涛漂, 由廠商定義。
以下是Nexus 5(hammerhead)耗電參數(shù)配置的代碼片段:

<device name="Android">
    <!-- All values are in mAh except as noted -->
    <item name="none">0</item>
    ...
    <item name="wifi.on">3.5</item>
    <item name="wifi.active">73.24</item>
    <item name="wifi.scan">75.48</item>
    ...
    <item name="battery.capacity">2300</item>
</device>
2. Android框架層通過一個(gè)名為batterystats的系統(tǒng)服務(wù)检诗,實(shí)現(xiàn)了電量統(tǒng)計(jì)的功能匈仗。

收集信息被組織起來,在內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)是由BatteryStats類描述的逢慌。 為了能夠從不同維度統(tǒng)計(jì)耗電量悠轩,這個(gè)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)得比較復(fù)雜,我們不在這里展開討論攻泼,僅通過一個(gè)收集應(yīng)用程序前臺(tái)運(yùn)行時(shí)間的例子哗蜈,來說明信息收集過程。
記錄應(yīng)用程序中所有Activity從顯示狀態(tài)(Resumed)到消失狀態(tài)(Paused)的時(shí)間坠韩,就能夠統(tǒng)計(jì)應(yīng)用程序的前臺(tái)運(yùn)行時(shí)間距潘。Activity狀態(tài)的切換是由AMS掌控的,因此AMS需要將Activity的狀態(tài)信息通知給batterystats服務(wù)只搁。
當(dāng)Activity要切換到顯示狀態(tài)(Resumed)時(shí)音比,
會(huì)調(diào)用ActivityStackSupervisor.resumeTopActivitiesLocked()方法,
接下來會(huì)調(diào)用ActivityStack.resumeTopActivityInnerLocked()方法來完成Activity的狀態(tài)切換氢惋,在完成狀態(tài)切換后洞翩, 會(huì)調(diào)用
ActivityStackSupervisor.reportResumedActivityLocked()方法,從這里開始焰望,就開始通報(bào)了:“本Activity已經(jīng)進(jìn)入了顯示狀態(tài)”骚亿。
在ActivityStackSupervisor.reportResumedActivityLocked()中得到BatteryStatsImpl對(duì)象, 并啟動(dòng)一個(gè)計(jì)時(shí)器(StopwatchTimer)熊赖,記錄下了啟動(dòng)時(shí)間.在Activity pause時(shí)来屠, 再得到結(jié)束時(shí)間, 這樣就得到了應(yīng)用程序的acitiviy在前臺(tái)的運(yùn)行時(shí)間了震鹉。

除了應(yīng)用程序前臺(tái)運(yùn)行時(shí)間俱笛,還有很多信息是batterystats服務(wù)關(guān)注的,包括WakeLock传趾、Sendor迎膜、Wifi、Audio浆兰、Video等磕仅,這些信息的采集方式與上述過程雷同珊豹,都會(huì)經(jīng)過以下步驟:

  1. 由相應(yīng)的模塊發(fā)起狀態(tài)變更的通知
  2. BatteryStats使用定時(shí)器記錄起止時(shí)間
電量信息的儲(chǔ)存

Android支持歷史電量信息的顯示的,如果重新啟動(dòng)Android榕订,那內(nèi)存中的數(shù)據(jù)就丟失了平夜, 所以需要把這些信息存儲(chǔ)到磁盤上,磁盤上的 /data/system/batterystats.bin 文件中就是電量信息的序列化數(shù)據(jù)卸亮。
batterystats服務(wù)啟動(dòng)時(shí)忽妒,會(huì)從 batterystats.bin 這個(gè)文件中讀取數(shù)據(jù),來初始化BatteryStats這個(gè)數(shù)據(jù)結(jié)構(gòu)兼贸。

電量計(jì)算

BatteryStatsHelper.refreshStats()承載了電量計(jì)算的全部過程段直,在需要顯示電量統(tǒng)計(jì)信息的地方,就可以通過BatteryStatsHelper這個(gè)類溶诞,來獲取統(tǒng)計(jì)完成的電量信息鸯檬。 Setting.apk就引用了這個(gè)類。電量計(jì)算大體可以分為兩塊:

1. AppUsage:應(yīng)用程序耗電量計(jì)算螺垢,是指每一個(gè)應(yīng)用程序使用硬件模塊所產(chǎn)生的耗電量

在BatteryStatsHelper.processAppUsage()這個(gè)方法中喧务,實(shí)現(xiàn)了應(yīng)用程序的電量計(jì)算(實(shí)際上統(tǒng)計(jì)的粒度是uid,不同的apk可以運(yùn)行在同一個(gè)uid)枉圃。

2. MiscUsage:其他雜項(xiàng)耗電量計(jì)算

所謂雜項(xiàng)功茴,其實(shí)就是用戶比較關(guān)心的一大類,包括:待機(jī)的耗電量孽亲、亮屏的耗電量坎穿、通話的耗電量、Wifi的耗電量等返劲,這個(gè)統(tǒng)計(jì)是系統(tǒng)層面的玲昧, 作為app的開發(fā)人員可以忽略掉這部分內(nèi)容。

我們來總結(jié)一下應(yīng)用程序的電量計(jì)算過程篮绿。Android通過一個(gè)名為BatteryStats.Uid的數(shù)據(jù)結(jié)構(gòu)來維護(hù)一個(gè)應(yīng)用程序的電量統(tǒng)計(jì)信息孵延。 這個(gè)數(shù)據(jù)結(jié)構(gòu)中,又包含很多子結(jié)構(gòu):

Proc:表示屬于Uid的進(jìn)程亲配,一個(gè)Uid中可能會(huì)有多個(gè)進(jìn)程尘应,每個(gè)進(jìn)程都有CPU占用時(shí)間
WakeLock:表示Uid持有的WakeLock鎖的電量統(tǒng)計(jì),一個(gè)Uid也可能會(huì)持有多個(gè)鎖
Mobile Radio:表示Uid使用數(shù)據(jù)流量的電量統(tǒng)計(jì)弃榨,譬如3G流量菩收、4G流量
Wifi:表示Uid使用wifi的電量統(tǒng)計(jì)
Sendor:表示Uid使用傳感器的電量統(tǒng)計(jì)

Android提供的dumpsys命令用于查看系統(tǒng)服務(wù)的信息, 將batterystats作為參數(shù)鲸睛,就能輸出完整的電量統(tǒng)計(jì)信息。

adb shell dumpsys batterystats
App電量優(yōu)化實(shí)踐
1. 打點(diǎn)網(wǎng)絡(luò)優(yōu)化

現(xiàn)在用戶操作的打點(diǎn)信息是實(shí)時(shí)上報(bào)坡贺, 每單擊一次菜單項(xiàng)就有大概1k的數(shù)據(jù)上傳. 可以把這打點(diǎn)上傳的執(zhí)行封裝起來官辈, 間隔一段時(shí)間統(tǒng)一上傳箱舞, 或是在特殊時(shí)間點(diǎn)統(tǒng)一上傳, 可以有效減少頻繁地使用wifi和mobile radio模塊拳亿。

dotting_network.png
TXD 發(fā)送數(shù)據(jù) Transmit(tx) Data 的簡寫形式
RXD 接收數(shù)據(jù) Receive(rx) Data 的簡寫形式
2. 盡量減少wakeLock的使用

例如現(xiàn)在的下載文件的邏輯, 應(yīng)該使用帶超時(shí)參數(shù)的acquire() API, 避免長時(shí)間使用wake lock.

DownloadThread.java
PowerManager.WakeLock wakeLock = null; 
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
wakeLock.acquire();
3. 使用prepn profile 工具實(shí)時(shí)檢測應(yīng)用的耗電量
trepn_profile.png

===DONE===

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晴股,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肺魁,更是在濱河造成了極大的恐慌电湘,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹅经,死亡現(xiàn)場離奇詭異寂呛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瘾晃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門贷痪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹦误,你說我怎么就攤上這事劫拢。” “怎么了强胰?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵舱沧,是天一觀的道長。 經(jīng)常有香客問我偶洋,道長狗唉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任涡真,我火速辦了婚禮分俯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哆料。我一直安慰自己缸剪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布东亦。 她就那樣靜靜地躺著杏节,像睡著了一般。 火紅的嫁衣襯著肌膚如雪典阵。 梳的紋絲不亂的頭發(fā)上奋渔,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音壮啊,去河邊找鬼嫉鲸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛歹啼,可吹牛的內(nèi)容都是我干的玄渗。 我是一名探鬼主播座菠,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼藤树!你這毒婦竟也來了浴滴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤岁钓,失蹤者是張志新(化名)和其女友劉穎升略,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屡限,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品嚣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了囚霸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腰根。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拓型,靈堂內(nèi)的尸體忽然破棺而出额嘿,到底是詐尸還是另有隱情,我是刑警寧澤劣挫,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布册养,位于F島的核電站,受9級(jí)特大地震影響压固,放射性物質(zhì)發(fā)生泄漏球拦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一帐我、第九天 我趴在偏房一處隱蔽的房頂上張望坎炼。 院中可真熱鬧,春花似錦拦键、人聲如沸谣光。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萄金。三九已至,卻和暖如春媚朦,著一層夾襖步出監(jiān)牢的瞬間氧敢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國打工询张, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留孙乖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像的圆,于是被迫代替她去往敵國和親鼓拧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子半火,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容