從 Android 6.0(API 級別 23)開始殉摔,Android 引入了兩個省電功能纯路,可通過管理應(yīng)用在設(shè)備未連接至電源時的行為方式為用戶延長電池壽命质欲。
低電耗(Doze)模式通過在設(shè)備長時間處于閑置狀態(tài)時推遲應(yīng)用的后臺 CPU 和網(wǎng)絡(luò) Activity 來減少電池消耗浸剩。
應(yīng)用待機(jī)(App Standby)模式可推遲用戶近期未與之交互的應(yīng)用的后臺網(wǎng)絡(luò) Activity零渐。
低電耗模式(Doze模式)
如果用戶設(shè)備未插接電源擦盾、處于靜止?fàn)顟B(tài)一段時間且屏幕關(guān)閉嘲驾,設(shè)備會進(jìn)入低電耗模式。 在低電耗模式下迹卢,系統(tǒng)會嘗試通過限制應(yīng)用對網(wǎng)絡(luò)和 CPU 密集型服務(wù)的訪問來節(jié)省電量辽故。 這還可以阻止應(yīng)用訪問網(wǎng)絡(luò)并推遲其作業(yè)、同步和標(biāo)準(zhǔn)鬧鈴腐碱。
系統(tǒng)會定期退出低電耗模式一會兒誊垢,好讓應(yīng)用完成其已推遲的 Activity。在此維護(hù)時段內(nèi),系統(tǒng)會運行所有待定同步喂走、作業(yè)和鬧鈴并允許應(yīng)用訪問網(wǎng)絡(luò)殃饿。
而 Android 7.0 則通過在設(shè)備未插接電源且屏幕關(guān)閉狀態(tài)下、但不一定要處于靜止?fàn)顟B(tài)(例如用戶外出時把手持式設(shè)備裝在口袋里)時應(yīng)用部分 CPU 和網(wǎng)絡(luò)限制缴啡,進(jìn)一步增強了低電耗模式壁晒。
圖 1. 低電耗模式如何應(yīng)用第一級系統(tǒng)活動限制以延長電池壽命的圖示。
7.0進(jìn)入Doze模式分兩個階段: 對App行為的限制分為light idle(淺度doze)和deep idle(深度doze).當(dāng)設(shè)備處于非充電狀態(tài)且屏幕已關(guān)閉一定時間后业栅,設(shè)備會進(jìn)入低電耗模式并應(yīng)用第一部分限制(light idle):關(guān)閉應(yīng)用網(wǎng)絡(luò)訪問秒咐、推遲作業(yè)和同步。如果進(jìn)入低電耗模式后設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時間碘裕,系統(tǒng)則會對 PowerManager.WakeLock携取、AlarmManager 鬧鈴、GPS 和 WLAN 掃描應(yīng)用余下的低電耗模式限制(deep idle)帮孔。無論是應(yīng)用部分還是全部低電耗模式限制雷滋,系統(tǒng)都會喚醒設(shè)備以提供簡短的維護(hù)時間窗口,在此窗口期間文兢,應(yīng)用程序可以訪問網(wǎng)絡(luò)并執(zhí)行任何被推遲的作業(yè)/同步晤斩。
light idle:(第一級限制,圖2中 第一個Doze階段)
進(jìn)入條件: 非充電狀態(tài)且屏幕已關(guān)閉一定時間后
限制: 關(guān)閉應(yīng)用網(wǎng)絡(luò)訪問、推遲作業(yè)和同步
deep idle:(第二級限制,圖2中 第二個Doze階段)
進(jìn)入條件: 進(jìn)入light idle模式后設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時間
限制: PowerManager.WakeLock姆坚、AlarmManager 鬧鈴澳泵、GPS 和 WLAN 掃描
在每個維護(hù)時段結(jié)束后,系統(tǒng)會再次進(jìn)入低電耗模式兼呵,暫停網(wǎng)絡(luò)訪問并推遲作業(yè)兔辅、同步和鬧鈴。 隨著時間的推移击喂,系統(tǒng)安排維護(hù)時段的次數(shù)越來越少维苔,這有助于在設(shè)備未連接至充電器的情況下長期處于不活動狀態(tài)時降低電池消耗。
圖 2. 低電耗模式如何在設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時間后應(yīng)用第二級系統(tǒng)活動限制的圖示懂昂。
圖中,橫軸表示隨著時間的推移,橙色表示設(shè)備處于喚醒運行狀態(tài),綠色表示低電耗(Doze)休眠狀態(tài);當(dāng)設(shè)備處于on battery(利用電池供電,也就是未插接電源),screen off(關(guān)閉屏幕),stationary(靜止?fàn)顟B(tài),7.0以后非靜止?fàn)顟B(tài)亦可)保持以上條件一段時間之后,設(shè)備就會進(jìn)入Doze模式.
maintenance window (低電耗(Doze)模式提供了定期維護(hù)時段,可供應(yīng)用使用網(wǎng)絡(luò)并處理待定Activity),Doze模式下會定期的進(jìn)入maintenance window,但進(jìn)入的間隔越來越長
一旦用戶通過移動設(shè)備介时、打開屏幕或連接到充電器喚醒設(shè)備,系統(tǒng)就會立即退出低電耗模式凌彬,并且所有應(yīng)用都將返回到正常 Activity沸柔。
低電耗模式限制
在低電耗模式下,您的應(yīng)用會受到以下限制:
- 暫停訪問網(wǎng)絡(luò)饿序。
- 系統(tǒng)將忽略 wake locks勉失。
- 標(biāo)準(zhǔn) AlarmManager 鬧鈴(包括 setExact() 和 setWindow())推遲到下一維護(hù)時段。
- 如果您需要設(shè)置在低電耗模式下觸發(fā)的鬧鈴原探,請使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()乱凿。
- 一般情況下顽素,使用 setAlarmClock() 設(shè)置的鬧鈴將繼續(xù)觸發(fā) — 但系統(tǒng)會在這些鬧鈴觸發(fā)之前不久退出低電耗模式。
- 系統(tǒng)不執(zhí)行 Wi-Fi 掃描徒蟆。
- 系統(tǒng)不允許運行同步適配器胁出。
- 系統(tǒng)不允許運行 JobScheduler。
應(yīng)用待機(jī)模式(App Standby)
應(yīng)用待機(jī)模式: 允許系統(tǒng)判定 應(yīng)用在用戶未主動使用它時,將應(yīng)用置為空閑狀態(tài);通俗的說是指用戶在一段時間內(nèi)沒有使用某個app,系統(tǒng)就會讓這個app處于空閑狀態(tài),空閑狀態(tài)會限制app訪問網(wǎng)絡(luò),推遲app的作業(yè)和同步任務(wù)
當(dāng)用戶有一段時間未觸摸應(yīng)用,且除以下條件外,都將被標(biāo)記為空閑狀態(tài)
- 用戶顯式啟動應(yīng)用(直接點擊app啟動)
- 應(yīng)用當(dāng)前有一個進(jìn)程位于前臺(表現(xiàn)為 Activity 或前臺服務(wù)形式段审,或被另一 Activity 或前臺服務(wù)占用)
- 應(yīng)用生成用戶可在鎖屏或通知托盤中看到的通知全蝶。
當(dāng)用戶將設(shè)備插入電源時,系統(tǒng)將從待機(jī)狀態(tài)釋放應(yīng)用寺枉,從而讓它們可以自由訪問網(wǎng)絡(luò)并執(zhí)行任何待定作業(yè)和同步抑淫。 如果設(shè)備長時間處于空閑狀態(tài),系統(tǒng)將按每天大約一次的頻率允許空閑應(yīng)用訪問網(wǎng)絡(luò)姥闪。
低電耗模式和應(yīng)用待機(jī)模式下進(jìn)行測試
為了確保用戶獲得極佳體驗始苇,您應(yīng)在低電耗模式和應(yīng)用待機(jī)模式下全面測試您的應(yīng)用
低電耗模式
您可按以下步驟測試低電耗模式:
- 1.使用 Android 6.0(API 級別 23)或更高版本的系統(tǒng)映像配置硬件設(shè)備或虛擬設(shè)備。
- 2.將設(shè)備連接到開發(fā)計算機(jī)并安裝應(yīng)用
- 3.運行應(yīng)用并使其保持活動狀態(tài)
- 4.關(guān)閉設(shè)備屏幕筐喳。(應(yīng)用保持活動狀態(tài)催式。)
- 5.通過運行以下命令強制系統(tǒng)在低電耗模式之間循環(huán)切換:
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
您可能需要多次運行第二個命令。不斷地重復(fù)避归,直到設(shè)備變?yōu)榭臻e狀態(tài)荣月。
- 6.在重新激活設(shè)備后觀察應(yīng)用的行為。確保應(yīng)用在設(shè)備退出低電耗模式時正呈岜校恢復(fù)哺窄。
應(yīng)用待機(jī)模式
要在應(yīng)用待機(jī)模式下測試您的應(yīng)用,請執(zhí)行以下操作:
- 1.使用 Android 6.0(API 級別 23)或更高版本的系統(tǒng)映像配置硬件設(shè)備或虛擬設(shè)備顿天。
- 2.將設(shè)備連接到開發(fā)計算機(jī)并安裝應(yīng)用
- 3.運行應(yīng)用并使其保持活動狀態(tài)
- 4.通過運行以下命令強制應(yīng)用進(jìn)入應(yīng)用待機(jī)模式:
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive <packageName> true
- 5.使用以下命令模擬喚醒應(yīng)用:
$ adb shell am set-inactive <packageName> false
$ adb shell am get-inactive <packageName>
- 6.觀察喚醒后的應(yīng)用行為堂氯。確保應(yīng)用從待機(jī)模式中正趁锏#恢復(fù)牌废。特別地,您應(yīng)檢查應(yīng)用的通知和后臺作業(yè)是否按預(yù)期繼續(xù)運行
親測MIUI 9.5執(zhí)行 adb shell am set-inactive com.tencent.mobileqq true 結(jié)果始終為: Idle=false 而測試其他包名則沒有異樣,也就是小米針對QQ這種用戶量大的即時通訊軟件做了針對性處理
Doze和App Standby白名單
通過妥善管理網(wǎng)絡(luò)連接啤握、鬧鈴鸟缕、作業(yè)和同步并使用 GCM 高優(yōu)先級消息,幾乎所有應(yīng)用都應(yīng)該能夠支持低電耗模式排抬。對于一小部分用例懂从,這可能還不夠。 對于此類用例蹲蒲,系統(tǒng)為部分免除低電耗模式和應(yīng)用待機(jī)模式優(yōu)化的應(yīng)用提供了一份可配置的白名單番甩。
在低電耗模式和應(yīng)用待機(jī)模式期間,加入白名單的應(yīng)用可以使用網(wǎng)絡(luò)并保留部分 wake locks届搁。 不過缘薛,正如其他應(yīng)用一樣窍育,其他限制仍然適用于加入白名單的應(yīng)用。 例如宴胧,加入白名單的應(yīng)用的作業(yè)和同步將推遲(在 API 級別 23 及更低級別中)漱抓,并且其常規(guī) AlarmManager 鬧鈴不會觸發(fā)。通過調(diào)用 isIgnoringBatteryOptimizations()恕齐,應(yīng)用可以檢查自身當(dāng)前是否位于豁免白名單中乞娄。
用戶可以在 Settings > Battery > Battery Optimization 中手動配置該白名單∠云纾或者仪或,系統(tǒng)會為應(yīng)用提供請求用戶將應(yīng)用加入白名單的方式。
- 應(yīng)用可以觸發(fā) ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS Intent士骤,讓用戶直接進(jìn)入 Battery Optimization溶其,他們可以在其中添加應(yīng)用。
- 具有 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 權(quán)限的應(yīng)用可以觸發(fā)系統(tǒng)對話框敦间,讓用戶無需轉(zhuǎn)到“設(shè)置”即可直接將應(yīng)用添加到白名單瓶逃。應(yīng)用將通過觸發(fā) ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent 來觸發(fā)該對話框。
boolean hasIgnored = powerManager.isIgnoringBatteryOptimizations(getPackageName());
if(!hasIgnored) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:"+getPackageName()));
startActivity(intent);
}
如何將非系統(tǒng)app預(yù)置到Doze的白名單中
- 用戶可以根據(jù)需要手動從白名單中移除應(yīng)用廓块。
在請求用戶將應(yīng)用添加到白名單之前厢绝,請確保應(yīng)用符合加入白名單的可接受用例。
注:除非應(yīng)用的核心功能受到不利影響带猴,否則 Google Play 政策禁止應(yīng)用請求直接豁免 Android 6.0+ 中的電源管理功能(低電耗模式和應(yīng)用待機(jī)模式)
DeviceIdleController
Android系統(tǒng)默認(rèn)是關(guān)閉Doze模式的,開啟Doze模式方式如下:
frameworks/base/core/res/res/values/config.xml
<bool name="config_enableAutoPowerModes">true</bool>
Doze模式的實現(xiàn)主要在/frameworks/base/services/core/java/com/android/server/DeviceIdleController.java
以上主要內(nèi)容參考自Google官方文檔 .