手機(jī)耗電的主要原因:
- 大數(shù)據(jù)量的傳輸;
- 不停的在網(wǎng)絡(luò)間切換;
- 解析大量的文本數(shù)據(jù);
- 內(nèi)存泄漏
電量統(tǒng)計(jì)公式
- 應(yīng)用運(yùn)行總時(shí)間 = 應(yīng)用在Linux內(nèi)核態(tài)運(yùn)行時(shí)間 + 應(yīng)用在Linux用戶態(tài)運(yùn)行時(shí)間`
- CPU工作總時(shí)間 = 軟件運(yùn)行期間CPU每個(gè)頻率下工作的時(shí)間之和比例`
-
應(yīng)用消耗的電量 = CPU每個(gè)頻率等級(jí)下工作的時(shí)間比例/CPU工作總時(shí)間 * 應(yīng)用運(yùn)行總時(shí)間`
設(shè)置中的電量排行
官方優(yōu)化建議
- 1:在需要網(wǎng)絡(luò)連接的程序中,首先檢查網(wǎng)絡(luò)連接是否正常,如果沒有網(wǎng)絡(luò)連接,那么就不需要執(zhí)行相應(yīng)的程序;
- 2:判斷網(wǎng)絡(luò)類型,針對(duì)特定的數(shù)據(jù)在特定的網(wǎng)絡(luò)下請(qǐng)求.例如:大量數(shù)據(jù)傳輸?shù)臅r(shí)候在wifi下請(qǐng)求;wifi下下載數(shù)據(jù)耗電量只有2/3/4G的1/3.
- 3:使用效率高的數(shù)據(jù)格式和解析方法,推薦使用JSON/ProtocolBuffer/FlutterBuffer;
- 4:在進(jìn)行大數(shù)據(jù)量下載時(shí),盡量使用GZIP方式下載;
- 5:使用推送,代替循環(huán)請(qǐng)求
- 6:盡量不要使用浮點(diǎn)運(yùn)算;
- 7:避免內(nèi)存抖動(dòng),減少GC的工作頻率。例如不要在for循環(huán)、onDraw方法中創(chuàng)建對(duì)象;無法避免的可以創(chuàng)建對(duì)象池,然后在不使用的時(shí)候釋放;
- 8:對(duì)定位要求不是太高的話盡量不要使用GPS定位,可以使用wifi和移動(dòng)網(wǎng)絡(luò)cell定位即可;
- 9:對(duì)于需要經(jīng)常獲取的信息可以使用緩存技術(shù),不需要進(jìn)行多次請(qǐng)求;
- 10:用JobScheduler 替代AlarmManager/WakeLock/Object#sleep()的定時(shí)任務(wù);
關(guān)注電量變化,在充電/電量過低時(shí)調(diào)整邏輯
-
在開始使用耗電模塊時(shí)考慮電量情況,例如電量過低時(shí)不要開啟gps定位
BatteryManager batteryManager = (BatteryManager)getSystemService(BATTERY_SERVICE); 得到電量數(shù)值,在0-100范圍內(nèi) int battery = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); 在耗電時(shí)監(jiān)聽電池電量顯著變化,可以注冊(cè)廣播
Intent.ACTION_BATTERY_LOW / Intent.ACTION_BATTERY_OKAY實(shí)現(xiàn)-
此外還可以注冊(cè)廣播
Intent.ACTION_POWER_CONNECTED / Intent.ACTION_POWER_DISCONNECTED監(jiān)聽充電行為public class PowerConnectionReceiver extends BroadcastReceiver { public static final ACTION_01 = Intent.ACTION_POWER_CONNECTED; public static final ACTION_02 = Intent.ACTION_POWER_DISCONNECTED; @Override public void onReceive(Context context, Intent intent) { int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 是否在充電 = (status == BatteryManager.BATTERY_STATUS_CHARGING) || status == BatteryManager.BATTERY_STATUS_FULL; 充電類型 = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); USB充電 = (充電類型 == BATTERY_PLUGGED_USB); AC電源充電 = (充電類型 == BATTERY_PLUGGED_AC); } }
使用Android Lint Tool規(guī)范代碼,排查問題
-
Android Sutido 集成的代碼規(guī)范提示工具,用來檢測(cè)代碼、xml布局文件、去除多余資源
參考:
/frameworks/base/services/core/java/com/android/server/job/controllers/BatteryController.java
參考:https://developer.android.google.cn/topic/performance/power
