版權聲明:本文由鄭桂濤原創文章,轉載請註明出處:
文章原文連接:https://www.qcloud.com/community/article/185shell
來源:騰雲閣 https://www.qcloud.com/community後端
從Android6.0開始,Android提供了兩種省電延長電池壽命的功能:Doze和App Standby;服務器
表現形式:當設備沒有鏈接到電源,設備進入Doze模式時,系統將經過延遲最近用戶沒有使用的應用程序的後臺CPU運做及網絡活動,讓應用程序處於App Standby狀態,以此來減小電池消耗。谷歌表示,在Nexus5和Nexus6上測試,當屏幕處於關閉狀態,平均續航時間提升30%;網絡
版本要求:Android6.0(API level 23)及其更高版本;app
開發者影響:爲了保證用戶的最佳體驗,開發者有必要在Doze和App Standby模式下測試應用程序,及其對代碼進行相應的調整。測試
用戶不操做設備一段時間優化
屏幕關閉spa
設備未鏈接電源充電server
系統試圖經過限制應用程序訪問網絡和CPU密集型服務節省電池;生命週期
防止應用程序訪問網絡,推延應用程序的工做,同步,和標準的警報;
系統按期提供一個短暫的時間讓應用程序完成延遲的工做活動,在這個時間片裏,系統將提供維持性窗口應用程序訪問網絡,運行在等待的同步,工做,和報警等活動。
Doze模式的五種狀態,分別以下:
ACTIVE:手機設備處於激活活動狀態
INACTIVE:屏幕關閉進入非活動狀態
IDLE_PENDING:每隔30分鐘讓App進入等待空閒預備狀態
IDLE:空閒狀態
IDLE_MAINTENANCE:處理掛起任務
以下圖所示,Doze期間提供間隔一小段時間(30s)供應用程序使用網絡和處理掛起的活動。
從這張圖咱們能夠看到,系統進入Doze模式後,系統會隔一段時間處理正在掛起的任務,隨着時間推移,後面間隔的時間會愈來愈長,以此來減小電量消耗。
用戶喚醒裝置移動,打開屏幕
或者設備鏈接電源
網絡鏈接會被禁止
Wake Lock會被屏蔽
AlarmManager定時任務延遲到下一個maintenance window進行處理,除非使用AlarmManager提供的方法:setAndAllowWhileIdle() 或者setExactAndAllowWhileIdle()
系統將不掃描熱點WIFI
同步工做將被禁止
不容許JobScheduler進行任務調度
Doze影響到AlarmManager鬧鐘和定時器管理活動,在Android6.0引入了兩個新方法:setAndAllowWhileIdle() 和setExactAndAllowWhileIdle(),調用兩個方法能夠在Doze模式下讓系統響應定時任務
Doze模式下限制了網絡的鏈接,若是應用程序依賴於實時信息,那麼這個將影響App的體驗。那麼你須要使用Google Cloud Messaging (GCM)谷歌雲消息(後面詳細講解)
測試Doze模式
首先確保你的硬件或虛擬設備是Android6.0或更高版本系統;
鏈接設備到開發機上並安裝你的app;
運行app並讓其運行活動;
關閉設備的屏幕;
運行如下adb命令使系統進入Doze模式:
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
觀察你的app表現行爲是否有需優化改進的地方。
測試App Standby模式
步驟1-3同測試Doze模式
運行如下adb命令迫使系統進入App Standby模式:
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive true
模擬喚醒你的應用程序使用如下命令:
$ adb shell am set-inactive false
$ adb shell am get-inactive
觀察你的App,確保應用程序恢復正常從待機模式過程當中,App的通知及其背部活動能達到預期結果。
當用戶不觸摸使用應用程序一段時間時,該應用程序處於App Standby狀態,系統將把該App標誌爲空閒狀態。除非觸發如下任意條件,應用程序將退出App Standby狀態:
用戶主動啓動該App;
該App當前有一個前臺進程(或包含一個活動的前臺服務,或被另外一個activity或前臺service使用);
App生成一個用戶所能在鎖屏或通知托盤看到的Notification, 而當用戶設備插入電源時,系統將會釋放App的待機狀態,容許他們自由的鏈接網絡及其執行未完成的工做和同步。若是設備空閒很長一段時間,系統將容許空閒App一天一次訪問網絡。
Doze模式須要屏幕關閉(一般晚上睡覺或長時間屏幕關閉纔會進入),而App Standby不須要屏幕關閉,App進入後臺一段時間也會受到鏈接網絡等限制。
Google Cloud Messaging(GCM)是一個雲到設備的服務,可讓你支持實時在雲端服務和Android設備上應用程序之間的消息傳遞。
GCM提供了一個持久鏈接到雲端的連接,讓全部須要實時消息傳遞應用程序能夠共享此連接。這個共享連接顯著優化電池消耗,使其沒必要讓多個應用程序各位維護本身單獨的持久連接而使電池迅速耗盡。
因爲這個緣由,官方建議:若是你的應用須要消息傳遞與後端服務集成,咱們強烈建議儘量的使用GCM,而不是單獨維護本身的網絡連接。
GCM消息擁有高優先級,不影響Doze模式,且不會不影響其餘應用程序的狀態。這意味着你的應用程序可使用它們進行通訊,同時最大限度地減小電池在整個系統和設備的影響。
如下來GCM自官方解釋:
一個GCM實現包括谷歌鏈接服務器,在你的環境中經過HTTP或XMPP協議的鏈接服務器進行交互的應用程序服務器和客戶端應用程序。
生命週期流程:
註冊啓用GCM: 客戶端應用程序註冊爲接收消息。
發送和接收下行消息:
發送一個消息,該應用程序服務器發送信息到客戶端應用程序:
1.該應用程序服務器發送消息給GCM鏈接服務器;
2.當設備處於脫機狀態,該GCM鏈接服務器入隊並存儲消息;
3.當設備聯機時,GCM鏈接服務器將郵件發送到該設備;
4.在設備上,所述客戶端應用程序根據該特定平臺實現接收該消息。
接收消息,客戶端應用程序收到一條消息從GCM鏈接服務器。
發送和接收上游的消息: 若是您使用的是此功能只提供XMPP鏈接服務器 。
發送一個消息,客戶端應用程序將消息發送到應用服務器:
1.在設備上,客戶端應用程序將消息發送到XMPP鏈接server;
2.若是該服務器已斷開鏈接,該XMPP服務器鏈接入隊並存儲信息;
3.當應用程序服務器從新鏈接後,XMPP鏈接服務器將郵件發送到應用程序服務器。
接收消息,一個應用服務器從XMPP鏈接服務器接收郵件,而後執行如下操做:
一、解析消息頭,以驗證客戶端應用程序發送的信息;
二、發送「確認」的XMPP鏈接服務器以確認收到該消息;
三、任選解析該消息有效載荷,由客戶端應用程序所定義的。
除了GCM,Android6.0及更高版本還提供了Doze模式白名單列表,經過設置應用程序進入白名單列表可逃脫Doze模式的各類限制。
檢測應用程序是否存在白名單list裏面,可以使用PowerManager的isIgnoringBatteryOptimizations()方法。
用戶也可手動設置應用程序進入白名單列表裏面,路徑爲:設置>電池>電池優化白名單:
客戶端使用方法:
App程序可發送action爲ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS的intent引導用戶進入設置界面將應用程序設置進白名單列表裏。
應用程序還可使用AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS 權限來觸發一個系統對話來讓用戶添加到白名單裏,而無需進入設置界面去設置。
固然,官方也提供用戶把你的App移除電池優化白名單的選項。這個白名單也會被Android M的另外一個新特性 App Standby使用,因此用戶只能簡單的進行控制,也就是說設備並不會徹底相信這個白名單。
官方舉了一下白名單例子:
$ adb shell dumpsys deviceidle whitelist +
$ adb shell dumpsys deviceidle
Doze模式的推出自己是爲了減小電池的消耗,且Google但願統一使用GCM來傳遞消息進行通信,而對於國內開發來說,確實帶來了很大的麻煩:
國內開發的一些消息推送機制(PUSH)將受到影響;
若使用GCM,在國內使用GCM延遲高,對於即時通信產品來講選擇還需勇氣啊;
國內第三方手機廠商如華爲、小米、三星,定製的Rom也將使用定製的推送消息機制。這讓同一款App如何選擇哪一種推送機制才能兼容呢?
用戶添加應用程序到電池優化白名單列表;
開發者使用Google提供的ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS意圖和AREQUEST_IGNORE_BATTERY_OPTIMIZATIONS權限設置以此忽略(推薦);
使用Google提供的GCM;
經過so繞過Doze模式。