Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android應用耗電分析與優化

Android應用耗電分析與優化

編輯:關於Android編程

應用的耗電是個長期持續優化的事情,而且隨著Android系統的不斷更新,系統本身也提供了越來越詳細的信息來輔助統計分析耗電。這裡基於Android 6.0介紹一些耗電分析與優化的思路及實踐,一方面可以在現有應用的基礎上直接使用,同時也可在後續的開發中注意和排查新功能可能帶來的耗電問題。

本文總的思路是先介紹官方的和已有的耗電分析思路和經驗,然後從統計、查找、分析並優化的步驟來作優化實踐
1.官方的建議
1.1 電池續航時間優化(Optimizing Battery Life)

已有中文的詳細說明,此處做簡要說明:
(1)監控電池電量和充電狀態(Monitoring the Battery Level and Charging State)
通過系統廣播,獲取充電狀態和電池電量的變化來調整數據更新等操作;如在充電時,更新數據及應用,在低電量時,減少更新頻率或停止gen
(2)確定和監控基座對接狀態和類型(Determining and Monitoring the Docking State and Type)
和監控充電狀態類似,通過系統廣播,獲取充電基座類型(車載基座、桌面基座),改變應用更新頻率和方式
(3)確定和監控網絡連接狀態(Determining and Monitoring the Connectivity Status)
也和監控充電狀態類似,根據當前連接網絡的類型采取不同的策略。一般情況WiFi耗電要比移動數據流量低很多。監聽CONNECTIVITY_CHANGE,可以在網絡狀態變化時調整策略
(4)根據需要操作廣播接收器(Manipulating Broadcast Receivers On Demand)
主要說明可通過PackageManager的setComponentEnabledSetting方法來改變組件的啟用與禁用。需要注意的是,此方法會導致應用的通知欄變化,不過系統會發送Intent.ACTION_PACKAGE_CHANGED廣播,而且要留心這種變化的持續性,避免誤認為廣播接收器偶爾不正常。


1.2 數據傳輸中減少耗電
此系列文章主要介紹與數據傳輸相關方面,減少電量消耗。首先,以3G數據網絡狀態機為例,說明無線射頻在standby 、low power 、full power三種狀態下的切換,一般減少頻繁的網絡連接,而延長在full power模式,獲取更多數據,如采取預獲取、合並獲取數據等;另一方面,減少不必要的重連接和獲取無用的數據;最後還是要區分在不同的網絡類型下,采用不同的策略,考慮GPRS等網絡實際的速度帶寬等


1.3 針對 Doze和App Standby的優化
在Android6.0上引入了Doze和應用的Standby。在Doze模式下,應用的網絡連接,CPU的使用都被嚴格控制,甚至喚醒鎖(wake lock)和普通的Alarm也被忽略,但是會周期性地退出,使應用可以完成被推遲的工作,如下的官方經典圖:
\

為了適配此種模式,一方面考慮其被延遲執行的影響(如心跳等),以及在後台,程序是否有必要執行某些操作,另一方面,它還是保留了setAlarmClock() 和提供setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle(),但應考慮不同設備,應用實際喚醒間隔時間。在官方描述是不少於9分鐘或者15分鐘。


應用的Standby,主要是指系統判定用戶不在使用應用時,推遲應用在後台的活動,包括網絡訪問、周期任務等;而判定的條件,排除此應用具有前台進程和具有通知欄。


然後都給出了測試方法,可以直接利用adb命令進入測試模式
(1)Doze
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
第二條指令需要執行多次
(2)Standby
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive  true
退出此模式:
$ adb shell am set-inactive  false
$ adb shell am get-inactive 

最後說明的是進入Doze是有比較嚴格的條件的,官方說明是在屏幕關閉後,沒有連接電源且沒有活動一定時間後(如1小時),而且屏幕一旦開啟或連接電源即退出Doze模式。同時系統也提供了白名單功能,如果覺得自己的應用進入Doze模式後,依然需要正常使用,可以通過ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS 引導用戶將自己加白。然而廠商實際執行可能會有差別,如在華為手機上,屏幕關閉幾分鐘後,應用就已經被掛起;定制ROM比較嚴重的廠商,還會對屏幕關閉後,執行殺死進程,關閉網絡等操作,都需要額外的考慮。細節不描述,因為這是保活的問題,但需要考慮對自身應用耗電的影響,比如心跳包無法發出,導致頻繁重連接,導致頻繁的證書交換(在此提及的原因是用https或者直接利用ssl,連接過程中驗證服務端都會涉及到證書鏈的下載,而單個證書可能就有幾K大小,證書鏈可能會到10K,特別是在數據網絡下,頻繁的連接帶來的消耗非常大)等都是耗電耗流量大戶。


2.其他經驗
此處的經驗是在電量統計的基礎上得出的(後面會做些電量統計的說明)。耗電大戶主要是設備喚醒、CPU和網絡、傳感器。
(1)設備喚醒單提出來說是因為通過Alarm可喚醒設備,而項目中不限制的濫用,導致系統被頻繁喚醒;再加上不恰當的使用wake lock,沒有釋放wake lock,使得系統長時間無法進入休眠,勢必導致高耗電。
( 2)CPU和網絡耗電方面,主要是減少I/O操作(包括數據庫操作),大量的計算;減少網絡網絡請求次數和數據量
(3)傳感器:設備屏幕亮度、顏色背景等需要考慮,但除了閱讀類等應用,一般是不太考慮屏幕消耗的。更多的是對GPS的使用注意,減少無用的GPS請求和及時關閉GPS搜索,比如室內是無法使用GPS完成定位的。

3.統計、查找、分析並優化實踐
此處的統計主要針對batterystats上進行。在Android5.0已經提供了adb shell dumpsys batterystats命令,而且在Android6.0上數據統計更詳細。官方的文檔Batterystats and Battery Historian Walkthrough,簡單的測試步驟:
(1)插入手機
$adb shell dumpsys batterystats --reset
(2)拔掉手機,開始測試
(3)$adb shell dumpsys batterystats > filename.txt 保存統計數據
然後可以下載並使用官方的python腳本生成html查看,也可以直接用文本文檔查看。統計數據中包括了詳盡的電量,wake lock,網絡使用的統計,具體到UID及其中的進程。列出一部分微信的在自己手機中使用的數據,有刪減:
u0a90:
  Mobile network: 908.38KB received, 144.94KB sent (packets 1063 received, 1219 sent)
  Mobile radio active: 5m 27s 337ms (31.9%) 15x @ 143 mspp
  Wi-Fi network: 3.52MB received, 454.37KB sent (packets 3628 received, 3645 sent)
  Wake lock WakerLock:180110109: 12s 444ms partial (52 times) realtime
  Wake lock *alarm*: 3s 362ms partial (24 times) realtime
    ...
  TOTAL wake: 59s 188ms partial realtime
  Foreground activities: 18m 37s 145ms realtime (32 times)
  Foreground for: 1h 49m 14s 993ms
  Total cpu time: u=3m 57s 240ms s=1m 4s 170ms p=0mAh
  Proc com.tencent.mm:tools:
  CPU: 1m 57s 260ms usr + 31s 570ms krn ; 0ms fg
  3 starts
  Proc com.tencent.mm:exdevice:
  CPU: 1s 290ms usr + 2s 590ms krn ; 0ms fg
  Proc com.tencent.mm:
  CPU: 1m 46s 610ms usr + 22s 920ms krn ; 4m 21s 940ms fg
  Proc com.tencent.mm:push:
  CPU: 7s 250ms usr + 5s 50ms krn ; 0ms fg
  Proc com.tencent.mm:sandbox:
  CPU: 0ms usr + 0ms krn ; 0ms fg
  1 starts
  Apk com.tencent.mm:
  Wakeup alarm *walarm*:ALARM_ACTION(7277): 22 times
  Wakeup alarm *walarm*:com.tencent.mm/.booter.MMReceivers$AlarmReceiver: 7 times
  Service com.tencent.mm.sandbox.updater.UpdaterService:
  Created for: 11s 53ms uptime
  Starts: 1, launches: 1
 ...
  Service com.tencent.mm.plugin.webview.stub.WebViewStubService:
  Created for: 0ms uptime
  Starts: 0, launches: 9

從上能夠分析出微信在這段測試時間詳細的網絡消耗,包括移動網絡和WiFi網絡,CPU的使用,Alarm,以及Service的啟動和運行時長等信息,基於此,再逐項排查和減少電量消耗。對於alarm的觸發,網絡的請求問題的定位從代碼上能比較方便的搜索到,但是CPU的消耗,則需要通過Android提供的Profiling工具來實現,它會幫你定位出CPU的時間都消耗在哪個函數上。網絡上有很多的使用教程。

簡單附上統計的說明:

應用UID:u0a90

移動網絡數據統計和時長統計

WiFi網絡數據統計

Wake lock統計,包括通過alarm觸發次數

應用前台頁面信息

CPU使用統計,包括各個進程的使用信息

Servce信息

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved