? ? ?在移動設(shè)備中,電池的重要性不言而喻,沒有電什么都干不成。對于操作系統(tǒng)和設(shè)備開發(fā)商來說,耗電優(yōu)化一致沒有停止,去追求更長的待機(jī)時間,而對于一款應(yīng)用來說,并不是可以忽略電量使用問題,特別是那些被歸為“電池殺手”的應(yīng)用,最終的結(jié)果是被卸載。因此,應(yīng)用開發(fā)者在實現(xiàn)需求的同時,需要盡量減少電量的消耗。在 Android5.0 以前,在應(yīng)用中測試電量消耗比較麻煩,也不準(zhǔn)確,5.0 之后專門引入了一個獲取設(shè)備上電量消耗信息的 API:Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統(tǒng)電量分析工具,和Systrace 一樣,是一款圖形化數(shù)據(jù)分析工具,直觀地展示出手機(jī)的電量消耗過程,通過輸入電量分析文件,顯示消耗情況。
1、重置、收集電量數(shù)據(jù)
命令如下:adb shell dumpsys batterystats --enable full-wake-histor
adb shell dumpsys batterystats --reset
2、獲取電量報告
adb bugreport > bugreport.txt
adb shell dumpsys batterystats > com.example.android.sunshine.app > batterystats.txt
將txt文檔轉(zhuǎn)化為html文件,命令如下:
python historian.py -a bugreport.txt > battery.html
打開html顯示如下




3、Battery History報告各個參數(shù)的意義
3.1、重要的參數(shù):WiFi、wake_lock、conn、mobile_ratio(蜂窩信號)

上面的30,0代表的就是秒的意思,它是以一分鐘為周期,到第60秒的時候變?yōu)?。橫坐標(biāo)就是一個時間范圍,咱們的例子中統(tǒng)計的數(shù)據(jù)是以重置為起點,獲取bugreport內(nèi)容時刻為終點。我們一共采集了多長時間的數(shù)據(jù),圖表下也有信息說明。
3.2、battery_level?
電量,可以看出電量的變化。比如上圖中的數(shù)據(jù)顯示剛開始電量是100%,然后在第11秒-12秒中間的某個時刻降到了99%

3.3、plugged?
充電狀態(tài),這一欄顯示是否進(jìn)行了充電,以及充電的時間范圍。例如上圖反映了我們在第22s插入了數(shù)據(jù)線,然后一直持續(xù)了數(shù)據(jù)采集結(jié)束。
3.4、screen?
屏幕是否點亮,這一點可以考慮到睡眠狀態(tài)和點亮狀態(tài)下電量的使用信息。
3.5、top?
該欄顯示當(dāng)前時刻哪個app處于最上層,就是當(dāng)前手機(jī)運(yùn)行的app,用來判斷某個app對手機(jī)電量的影響,這樣也能判斷出該app的耗電量信息。該欄記錄了應(yīng)用在某一個時刻啟動,以及運(yùn)行的時間,這對我們比對不同應(yīng)用對性能的影響有很大的幫助。
3.6、wake_lock*
wake_lock 該屬性是記錄wake_lock模塊的工作時間。是否有停止的時候等
3.7、running?
界面的狀態(tài),主要判斷是否處于idle的狀態(tài)。用來判斷無操作狀態(tài)下電量的消耗。
3.8、wake_lock_in*
wake_lock有不同的組件,這個地方記錄在某一個時刻,有哪些部件開始工作,以及工作的時間。
3.9、gps?
gps是否開啟
3.10、phone_in_call?
是否進(jìn)行通話
3.11、Sync?
是否跟后臺同步.?
可以把鼠標(biāo)停在某一項上面??梢钥吹胶螘rsync同步 啟動的,持續(xù)時間Duration多久。電池容量不會顯示單一行為消耗的具體電量,這里只能顯示使用電池的頻率和時長,你可以看分時段的剩余電量來了解具體消耗了多少電量。?
3.12、Job?
后臺的工作,比如服務(wù)service的運(yùn)行。從下面圖中可以看到qihoo的AppStore和魯大師都在運(yùn)行后臺服務(wù)。?
3.13、data_conn*
數(shù)據(jù)連接方式的改變,上面的edge是說明采用的gprs的方式連接網(wǎng)絡(luò)的。此數(shù)據(jù)可以看出手機(jī)是使用2g,3g,4g還是wifi進(jìn)行數(shù)據(jù)交換的。這一欄可以看出不同的連接方式對電量使用的影響。
3.14、status?
電池狀態(tài)信息,有充電,放電,未充電,已充滿,未知等不同狀態(tài)。 這一欄記錄了電池狀態(tài)的改變信息。
3.15、phone_signal_strength?
手機(jī)信號狀態(tài)的改變。 這一欄記錄手機(jī)信號的強(qiáng)弱變化圖,依次來判斷手機(jī)信號對電量的影響。
3.16、health?
電池健康狀態(tài)的信息,這個信息一定程度上反映了這塊電池使用了多長時間。 這一欄記錄電池狀態(tài)在何時發(fā)生改變,上面的圖中電池狀態(tài)一直處于good狀態(tài)。
3.17 、plug?
充電方式,usb或者插座,以及顯示連接的時間。 這一欄顯示了不同的充電方式對電量使用的影響。
4、其他方案
4.1、計算優(yōu)化,避開浮點運(yùn)算等,減少CPU的占用。
4.2、使用 Job Schedule
4.3、使用workManager
4.4、避免 WaleLock 使用不當(dāng)。
WakeLock 是為了保持設(shè)備的喚醒狀態(tài)的API,組織用戶長時間不用,仍然需要組織設(shè)備進(jìn)入休眠的狀態(tài),比如用戶在看電影的時候。使用wakelock 時,需要及時的釋放鎖,比如播放視屏的時候WakeLock保持屏幕的常亮,在暫停的時候就應(yīng)該釋放鎖,而不是等到停止播放才釋放。
4.5、AlarmManager
AlarmManager 也是比較耗電的,通常情況下需要保證兩次喚醒操作的時間間隔不要太短了,在不需要使用喚醒功能的情況下,盡早的取消喚醒功能,否則應(yīng)用會一直消耗電量 AlarmManager 是SDK提供的一個喚醒的APi,是系統(tǒng)級別的服務(wù),可以在特定的時刻廣播一個指定的Intent,這個pendingIntent可以用來啟動Activity、Service、BroadcastReceiver, app,在后臺也會啟動。
4.6、數(shù)據(jù)傳輸
?數(shù)據(jù)傳輸 ? ?藍(lán)牙傳輸,Wi-Fi傳輸 ?移動網(wǎng)絡(luò)傳輸 ?后臺數(shù)據(jù)的管理:根據(jù)業(yè)務(wù)需求,接口盡量避免無效數(shù)據(jù)的傳輸 ?數(shù)據(jù)傳輸?shù)念l度問題:通過經(jīng)驗值或者是數(shù)據(jù)統(tǒng)計的方法確定好數(shù)據(jù)傳輸?shù)念l度,避免冗余重復(fù)的數(shù)據(jù)傳輸,數(shù)據(jù)傳輸過程中要壓縮數(shù)據(jù)的大小,合并網(wǎng)絡(luò)請求,避免輪詢。
4.7、位置服務(wù)?
正確的使用位置復(fù)位,是應(yīng)用耗電的一個關(guān)鍵。
網(wǎng)絡(luò)優(yōu)化
? ? ?網(wǎng)絡(luò)優(yōu)化. 移動端對額App幾乎都是聯(lián)網(wǎng)的,網(wǎng)絡(luò)延遲等會對App的性能產(chǎn)生較大的影響,網(wǎng)絡(luò)優(yōu)化可以節(jié)約網(wǎng)絡(luò)流量和電量。我們可以從如下幾個方面入手:
5.1、合并網(wǎng)絡(luò)請求,一次完整的Http請求,首先進(jìn)行的是DNS查找,通過TCP三次握手,從而建立連接,如果是https請求的話,還要經(jīng)過TLS握手成功后才可以進(jìn)行連接,對于網(wǎng)絡(luò)請求,減少接口,能夠合并的網(wǎng)絡(luò)請求就盡量合并。
5.2、盡量避免網(wǎng)絡(luò)請求失敗時候,無限制的循環(huán)重試連接。
5.3、預(yù)先獲取數(shù)據(jù)能夠?qū)⒕W(wǎng)絡(luò)請求集中在一次,這樣其他時間段手機(jī)就可以切換到空閑的時間,從而避免經(jīng)常性的喚醒,從而節(jié)約用電。
5.4、避免輪詢:如果說每個一段時間需要向服務(wù)器發(fā)起主動的網(wǎng)絡(luò)請求,其實不建議在app端做這樣的操作,可以使用推送,如果說在不得已的情況下,也要避免使用Thread.sleep()函數(shù)來循環(huán)等待,建議使用系統(tǒng)的AlarmManager來實現(xiàn)定時輪詢,AlarmManager 可以保證在系統(tǒng)休眠的時候,CPU也可以得到休息,在下一次需要發(fā)起網(wǎng)絡(luò)球球的時候才喚醒。
5.5、離線緩存,對于圖片或者文件,內(nèi)存緩存+磁盤緩存+網(wǎng)絡(luò)緩存,一般我們本地需要做的是二級緩存,當(dāng)緩存中存在圖片或者是文件,直接從緩存中讀取,不會走網(wǎng)絡(luò),下載圖片,在Android中使用LruCache實現(xiàn)內(nèi)存緩存,DiskLruCache實現(xiàn)本地緩存。
5.6、壓縮數(shù)據(jù)的大?。嚎梢詫Πl(fā)送服務(wù)端數(shù)據(jù)進(jìn)行g(shù)zip壓縮,,使用webp格式代替圖片格式。
5.7、不同的網(wǎng)絡(luò)環(huán)境使用不同的超時策略,常見的網(wǎng)絡(luò)格式有 2g、3g、4g、wifi,實時的更新當(dāng)前的網(wǎng)絡(luò)狀態(tài),通過監(jiān)聽來獲取最新的網(wǎng)絡(luò)類型,并動態(tài)調(diào)整網(wǎng)絡(luò)超時的時間。
5.8、CDN的全稱是Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。其基本思路是盡可能避開互聯(lián)網(wǎng)上有可能影響數(shù)據(jù)傳輸速度和穩(wěn)定性的瓶頸和環(huán)節(jié),使內(nèi)容傳輸?shù)母?、更穩(wěn)定。通過在網(wǎng)絡(luò)各處放置節(jié)點服務(wù)器所構(gòu)成的在現(xiàn)有的互聯(lián)網(wǎng)基礎(chǔ)之上的一層智能虛擬網(wǎng)絡(luò),CDN系統(tǒng)能夠?qū)崟r地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點的連接、負(fù)載狀況以及到用戶的距離和響應(yīng)時間等綜合信息將用戶的請求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點上。其目的是使用戶可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況,提高用戶訪問網(wǎng)站的響應(yīng)速度。