標籤:fonts download 即時通 filter mission status 雲端 localhost action
最近領導老是反映說我們的APP耗電要比以前厲害一些,排在耗電量的首位,上黑名單了,需要進行電量最佳化!經過一段時間的研究,自己做了一部分的總結!
電量最佳化的工具battery-historien
battery-historien是google開源的電量檢測分析的工具,由於很多APP開發人員對電量這快關注不是那麼多,star數並不是特別多!
連結:https://github.com/google/battery-historian上面有具體環境搭建步驟!
環境搭建步驟
我使用的是方法二,步驟如下:
1.下載go,安裝,指定path路徑2.下載python,安裝,指定path3.下載git,安裝4.下載Java,安裝,指定path5.下載源碼 go get -d -u github.com/google/battery-historian/…6.運行源碼,下載依賴 cd $GOPATH/src/github.com/google/battery-historian go run setup.go 發現下載不下來,手動下載closure-library,closure-compiler,flot-axislabels 分別解壓到third_party下面7.運行監聽 go run cmd/battery-historian/battery-historian.go 2017/04/16 18:23:02 Listening on port: 99998.檢驗運行情況 http://localhost:9999 2017/04/16 18:23:09 Trace starting analysisServer processing for: GET2017/04/16 18:23:09 Trace finished analysisServer processing for: GET
匯出電量檔案與分析匯出檔案
匯出檔案使用ADB命令來組建檔案:
adb kill-serveradb start-server// 開啟電池資料擷取adb shell dumpsys batterystats --enable full-wake-history// 電池資料重設adb shell dumpsys batterystats --reset// 產生電量資料到檔案adb bugreport > bugreport.txt
分析檔案:
分析檔案有兩種方式:
上傳檔案分析
一是上傳檔案到伺服器進行分析,但是不知道什麼原因,失敗了!
在battery-historian目錄下開啟GUI bash,執行:
go run cmd/battery-historian/battery-historian.gohistorian.py瀏覽器開啟:http://localhost:9999/但是並沒有什麼卵用!產生的txt檔案是無法上傳進行分析的,可能是因為不相容
選擇產生的檔案之後就沒有後文了!表示很傷心!果斷使用第二種!
轉換為html檔案分析
使用python指令碼進行分析,下載指令碼到相應目錄
使用命令將txt產生html檔案:
python historian.py -a bugreport.txt > battery.htmlWARNING: Visualizer disabled. If you see this message, download the HTML then open it.需要翻牆
開啟html檔案就可以看到電量消耗情況:
欄位分析
plugged 充電狀態top 那個app運行在最上面sync 跟背景同步處理wake_lock cpu的喚醒鎖job 服務,背景工作runningconnectionwifimobile_ratio 蜂窩訊號
主要耗電的地方:螢幕亮屏,蜂窩移動資料(3G,4G),WIFI,CPU/GPU工作,我們需要特別關注這些方面!
最佳化策略
電量最佳化策略:
1.充電進行某些操作
某些不需要及時與使用者進行互動的操作,可以放到充電後再進行,比如拍照後圖片處理,360手機小幫手在手機充電後才自動清理
垃圾,連絡人資料上傳到雲端等等。。。
監聽電池充電操作 IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);Intent batteryStatus = this.registerReceiver(null, filter);//幾種充電方式:直流充電,USB充電,無線充電 int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); boolean usbCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_USB); boolean acCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_AC); boolean wirelessCharge = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { wirelessCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS); } return (usbCharge || acCharge || wirelessCharge); }
2.WIFI狀態下進行操作
我們知道在蜂窩無線網路狀態下會比WIFI狀態下耗電的多,所以盡量減少移動網路下的資料轉送,多在WIFI資料下操作! //判斷網路連接 private boolean isNetWorkConnected() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return (activeNetworkInfo!=null&&activeNetworkInfo.isConnected()); }
3.網路請求設定逾時
在網路請求時,如果網路很差,請求需要很長時間,我們需要設定逾時時間,減少網路消耗!
4.任務集中處理JobScheduler
使用JobScheduler來處理一些特定的操作
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); for (int i = 0; i < 10; i++) { JobInfo jobInfo = new JobInfo.Builder(i,componentname) .setMinimumLatency(10000)//最小延時 .setOverrideDeadline(60000)//最多執行時間// .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//免費的網路(wifi/藍芽/USB),滿足該條件才去執行.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)//任意網路---wifi .build(); jobScheduler.schedule(jobInfo); }// 任務處理public class JobServiceTest extends JobService {}缺點就是有API限制
大量集中的操作可以一起處理
5.WEAK_LOCK謹慎使用
WEAK_LOCK主要是用來處理系統休眠的,我們知道系統為了省電一般會在熄屏之後進行休眠,休眠之後所有的操作就會被暫停冷凍了(Timer,Services),
休眠之後一些背景網路訪問操作就會被停止,可能就會導致一些問題,比如即時通訊的心跳包不能及時發出,導致收不到訊息,
為了防止這些情況,需要使用WEAK_LOCK來喚醒CPU,權利配合我們的程式執行!
wake_lock:兩種鎖,一種計數鎖(鎖一次,釋放一次);非計數鎖(鎖了很多次,只需要release一次就可以解除了
使用WEAK_LOCK:
// 註冊許可權<uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakelockTag"); mWakelock.acquire();//喚醒CPU mWakelock.release();//釋放CPU鎖注意:在使用該類的時候,必須保證acquire和release是成對出現的。
需要注意
1.喚醒CPU頻率
喚醒CPU的頻率也不能太高,不然可能會出現一些問題,比如小米手機做了同步心跳(心跳對齊),如果超出了這個心跳的頻率,就會被屏蔽或者降頻!
2.使用AlarmManager
AlarmManager是系統的鬧鐘服務,可以用來喚醒CPU,做一些背景任務,即使在螢幕熄滅後也能正常的工作(定時任務盡量不要使用Timer、Handler、Thread、Service)
Intent intent = new Intent(context, Service.class);PendingIntent pi = PendingIntent.getService(context, 1, intent, 0);AlarmManager alarm = (AlarmManager) getSystemService(Service.ALARM_SERVICE);if(alarm != null){ alarm.cancel(pi); // 鬧鐘在系統睡眠狀態下會喚醒系統並執行提示功能 alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, 2000, pi);// 確切的時間鬧鐘//alarm.setExact(…); //alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);}
3.保持螢幕常量
在螢幕關閉之後,系統休眠,一些任務可能會被暫停(Timer、Handler、Thread、Service),但是某些情況下我們需要保持螢幕常量,或者不需要螢幕常量但是需要CPU一直執行,直到任務的執行完成,那麼我們可以手動設定螢幕常亮!
//在Acitivty裡面使用FlaggetWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);FLAG_KEEP_SCREEN_ON的好處是使用方便,不要額外的許可權!
Android電量最佳化