前言
從Android 6.0開始,谷歌引入了Doze模式(打盹模式)的省電技術延長電池使用時間。如果用戶長時間未使用設備,低電耗模式會延遲應用后臺 CPU 和網絡活動,從而延長電池續航時間。根據第三方測試顯示,兩臺同樣的Nexus 5,開啟的Doze的一臺待機能達到533小時,而未開啟Doze的一臺待機只能達到200小時。Doze省電效果十分明顯。
Doze省電技術原理
Doze模式細分light idle和deep idle,本文主要介紹deep idle
操作 | 低電耗模式-deep idle | 輕度低電耗模式-light idle |
觸發器 | 屏幕關閉、電池供電(未插電)、靜止 | 屏幕關閉、電池供電(未插電) |
計時 | 隨維護時段依次增加 | 隨維護時段反復持續 N 分鐘 |
限制 | 無法訪問網絡、喚醒鎖定和 GPS/WLAN 掃描;鬧鐘和作業/同步被延遲 | 無法訪問網絡;作業/同步被延遲(維護窗口除外) |
行為 | 僅接收優先級較高的推送通知消息 | 接收所有實時消息(即時消息、致電等);優先級較高的推送通知消息可以暫時訪問網絡 |
退出 | 動作、屏幕開啟或鬧鐘響鈴 | 屏幕開啟 |
Doze技術原理主要分為狀態機+省電管控(后臺 CPU 和網絡活動)措施,延長待機續航的效果。
其中狀態機的目的主要識別用戶長時間未使用設備場景并標記Idle狀態,省電管控措施主要是Idle狀態內限制應用后臺 CPU 和網絡活動
1.DeepIde狀態機
為了更好地識別用戶未使用場景,Doze模式設計了狀態機機制,主要包含長期滅屏、無運動、無顯著運動、無GPS變化的狀態檢測與流轉。其中運動檢測和GPS側重的是靜止狀態的識別。
1.1 DeepIde狀態機時序圖
待機滅屏時會先開啟一個30分鐘的鬧鐘檢測滅屏狀態持續30分鐘,滿足滅屏待機30分鐘后,再開啟30分鐘的低功耗運動檢測查看是否為靜止狀態,滿足30分鐘保持靜止狀態后,再開啟4分鐘的高精度ACC動作檢測是否是絕對靜止狀態,滿足4分鐘持續的絕對靜止狀態后,再開啟30秒的GPS定位檢測是否沒有定位變化,滿足30秒沒有定位條件,就可以進入deep idle狀態,對可以放心對操作系統層上的應用進行功耗限制了。
// 30分鐘的待機滅屏時長檢測定義
private long mDefaultInactiveTimeout =
(30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
// 30分鐘的低功耗普通運動檢測
private long mDefaultIdleAfterInactiveTimeout =
(30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
// 4分鐘的高耗電高精度的ACC運動檢測
private long mDefaultSensingTimeout =
!COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L;
// 30秒的GPS位置檢測
private long mDefaultLocatingTimeout =
!COMPRESS_TIME ? 30 * 1000L : 15 * 1000L;
從上述時序圖可以看出,進入deep idle需要1小時4.5mins,idle周期時間為1小時、2小時、4小時、最大6小時,維護窗口時間為5mins。
移動檢測:主要分為SIGNIFICANT_SENSOR檢測和加速度傳感器檢測,區別是一個低功耗精度沒那么高和一個高功耗精度高
1.2 DeepIde 狀態機流轉圖
注:QUICK_DOZE_DELAY是一種特殊狀態,當設備處于低電量時會進入,因此正常情況LOCATING會切換到IDLE的,只是代碼會執行到QUICK_DOZE_DELAY的。
1.3 Deep Idle 狀態機狀態轉換表
狀態 (State) | 進入條件 (Entry Conditions) | 觸發方法/邏輯 |
STATE_ACTIVE | 屏幕開啟 OR 正在充電 OR 即將觸發鬧鐘 OR 有緊急呼叫活躍。 | 初始狀態,通過 becomeActiveLocked() 激活。 |
STATE_INACTIVE | 屏幕關閉 AND 未充電 AND 無緊急呼叫。 | becomeInactiveIfAppropriateLocked()(且未啟用 Quick Doze)。 |
STATE_QUICK_DOZE_DELAY | 同 STATE_INACTIVE,且關閉了位置、運動檢測和顯著運動監控。 | becomeInactiveIfAppropriateLocked()(且啟用 Quick Doze)。 |
STATE_IDLE_PENDING | 開啟顯著運動監控(等待檢測運動)。 | 從 STATE_INACTIVE 通過 stepIdleStateLocked() 進入。 |
STATE_SENSING | 監控任意運動(包括顯著運動和普通運動)。 | 從 STATE_IDLE_PENDING 通過 stepIdleStateLocked() 進入。 |
STATE_LOCATING | 正在請求位置信息,且運動監控仍開啟。 | 從 STATE_SENSING 通過 stepIdleStateLocked() 進入。 |
STATE_IDLE | 關閉位置和運動檢測,保持顯著運動監控狀態不變。 | 從 STATE_SENSING(無位置服務)或 STATE_LOCATING/STATE_QUICK_DOZE_DELAY 通過 stepIdleStateLocked() 進入。 |
STATE_IDLE_MAINTENANCE | 空閑維護窗口(短暫喚醒以執行任務)。 | 從 STATE_IDLE 通過 stepIdleStateLocked() 進入。 |
2.DeepIde 省電管控措施
進入deep idle需要1小時4.5mins,deep idle周期時間為1小時、2小時、4小時、最大6小時,維護窗口時間為5mins。窗口期的意思就是每1,2,4,6小時的間隔留5分鐘放風期,讓被限制的應用有機會臨時解除限制,進行后臺活動,例如消息推送接收或數據同步。這里也體現出批量放風的功耗管控思維。
在休眠Idle期間,設備會受到以下限制:
1.應用無法訪問網絡。
2.應用喚醒鎖定被忽略。
3.鬧鐘被延遲。鬧鐘響鈴以及使用
setAndAllowWhileIdle() 設置的鬧鐘(當設備處于低電耗模式時,限于每個應用每 15 分鐘 1 次)除外。此豁免規則適用于必須顯示活動提醒通知的應用(如日歷)。
4.無法執行 WLAN 掃描。
5.SyncAdapter 同步和
JobScheduler 作業被延遲,直到下一個維護時段才能恢復。
6.接收短信和彩信的應用被暫時列入白名單,以便它們可以完成處理任務。
3.退出DeepIde的機制
當平臺檢測到以下任意情況時,會使設備退出低電耗模式,從這里我們可以看出Doze模式進入是嚴進寬出的模式
1.用戶與設備互動
2.設備移動操作
3.設備屏幕打開
4.AlarmClock 即將響鈴
備注:消息通知不會使設備退出低電耗模式。
4.Doze白名單分類
什么時候配置白名單呢?一般是應用因被doze管控,導致一些消息接收不及時,需要根據是否第三方應用或系統內置應用進行不同路徑的配置文件進行配置。
變量名 | 加載方式 | 作用范圍 | 調用場景 | 組成/備注 |
用戶應用白名單 | ||||
mPowerSaveWhitelistUserApps | onStart中通過config文件加載 | 省電模式下所有用戶應用 | 直接調用 | 基礎用戶白名單列表 |
mPowerSaveWhitelistUserAppIds | 由mPowerSaveWhitelistUserApps生成 | 同mPowerSaveWhitelistUserApps | 僅用于dump打印 | 用戶白名單的ID形式(如UID) |
mPowerSaveWhitelistUserAppIdArray | 同mPowerSaveWhitelistUserAppIds | 同mPowerSaveWhitelistUserApps | 提供Binder遠程調用 | 用戶白名單ID數組,供AMS/PMS訪問 |
系統應用白名單 | ||||
mPowerSaveWhitelistSystemAppIds | onStart中通過config文件加載 | 所有省電模式下的系統應用 | 直接調用 | 基礎系統白名單(含IDLE場景) |
mPowerSaveWhitelistSystemAppIdsExceptIdle | onStart中通過配置文件加載 | 省電模式但排除IDLE狀態的系統應用 | Binder遠程增刪 | 系統白名單的子集(IDLE狀態不生效) |
混合白名單 | ||||
mPowerSaveWhitelistAllAppIds | 由以下兩者組成: | 所有省電模式下的全部應用(系統+用戶) | 僅用于dump打印 | mPowerSaveWhitelistApps + mPowerSaveWhitelistUserApps |
mPowerSaveWhitelistAllAppIdArray | 同mPowerSaveWhitelistAllAppIds | 同mPowerSaveWhitelistAllAppIds | 向AMS/PMS設置全局白名單 | 全局白名單的數組形式,供系統服務調用 |
排除IDLE的白名單 | ||||
mPowerSaveWhitelistExceptIdleAppIds | 由以下兩者組成: | 省電模式但排除IDLE狀態的全部應用 | 無直接調用(僅邏輯組合) | mPowerSaveWhitelistAppsExceptIdle + mPowerSaveWhitelistUserApps |
mPowerSaveWhitelistExceptIdleAppIdArray | 同mPowerSaveWhitelistExceptIdleAppIds | 同mPowerSaveWhitelistExceptIdleAppIds | Binder遠程調用 | 排除IDLE的白名單數組,功能與mPowerSaveWhitelistExceptIdleAppIds一致 |
Android手機的Settings也提供了Doze白名單的手動設置入口:
如果不配置白名單,新安裝的應用默認是歸為doze的自動管控規則,即優化選項