Android Doze低電耗休眠模式 與 WorkManager

1. Doze模式下,WorkManager setInitialDelay設置小于15分鐘,被系統強制到15分鐘執行,怎么辦 ?

Android 擁有兩項省電功能,通過管理設備未連接電源時應用的行為來延長用戶電池續航時間:低電耗模式 (Doze) 和應用待機模式 (App Standby)。 低電耗模式 通過延遲設備長時間未使用時應用的后臺 CPU 和網絡活動來降低電池消耗。 應用待機模式 延遲沒有近期用戶活動的應用的后臺網絡活動。

設備處于低電耗模式時,應用對某些耗電資源的訪問會被延遲,直到維護窗口。 具體限制列在電量管理限制中。

低電耗模式和應用待機模式管理在 Android 6.0 或更高版本上運行的所有應用的行為,無論它們是否專門針對 API 級別 23。為了幫助確保為用戶提供最佳體驗,請在低電耗模式和應用待機模式下測試您的應用,并對您的代碼進行任何必要的調整。以下部分提供詳細信息。

2. 了解低電耗模式(Doze)

如果用戶將設備拔下電源并長時間靜置,且屏幕關閉,設備就會進入低電耗模式。在低電耗模式下,系統會嘗試通過限制應用對網絡和 CPU 密集型服務的訪問來節省電池電量。它還會阻止應用訪問網絡,并延遲其作業、同步和標準鬧鐘。

系統會定期短暫退出低電耗模式,讓應用完成其延遲的活動。在此 維護窗口 期間,系統會運行所有待處理的同步、作業和鬧鐘,并允許應用訪問網絡。
在這里插入圖片描述
維護窗口結束后,系統會再次進入低電耗模式,暫停網絡訪問并延遲作業、同步和鬧鐘。隨著時間的推移,系統安排維護窗口的頻率會降低,有助于在設備未充電且長時間不活動的情況下減少電池消耗。

當用戶通過移動設備、打開屏幕或連接充電器來喚醒設備時,系統會退出低電耗模式,所有應用都會恢復正常活動。

3. 低電耗模式限制

設備處于低電耗模式時,系統會對您的應用施加以下限制:

  • 暫停網絡訪問。
  • 忽略喚醒鎖。
  • 將標準 AlarmManager 鬧鐘(包括 setExact() 和 setWindow())延遲到下一個維護窗口。
    • 如果您需要在低電耗模式下觸發鬧鐘,請使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
    • 通過 setAlarmClock() 設置的鬧鐘會正常觸發。系統會在這些鬧鐘觸發前不久退出低電耗模式。
  • 不執行 Wi-Fi 掃描。
  • 不允許同步適配器運行。
  • 不允許 JobScheduler 運行。

?? WorkManager 內部使用 JobScheduler,因此 WorkManager 任務不會運行。

具體詳見 Android Developer | doze-standby

4. Doze模式下,WorkManager 為何無法精確時間執行 ?

通過上文,我們可以知道,在Doze模式下,WorkManager 任務不會運行,只有在兩個Doze間隔期間,系統會定期短暫退出低電耗模式,讓應用完成其延遲的活動。在此 維護窗口 期間,系統會運行所有待處理的同步、作業和鬧鐘,并允許應用訪問網絡。 這個時候WorkManager的任務才會被執行。但是兩個Doze之間休眠時間的間隔是不確定的,所以Doze模式下,WorkManager無法精確時間被執行。

且如果WorkManager.setInitialDelay設置的時間小于15分鐘,會被系統強制替換為15分鐘。
那如果我就想10分鐘后執行,需要怎么辦呢 ?

5. Doze模式下,如何精確時間執行 ?

這個時候,就需要使用AlarmManager的setExactAndAllowWhileIdle方法了。 (雖然WorkManager在Android低版本上也是用的AlarmManager,但是并沒有使用AlarmManager的setExactAndAllowWhileIdle方法)

那么如何使用呢 ?

5.1 ??聲明權限?

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

5.2 調用前需驗證是否已授權

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);if (!alarmManager.canScheduleExactAlarms()) {// 引導用戶前往設置頁授權Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);intent.setData(Uri.parse("package:" + getPackageName()));startActivity(intent);return;}
}

5.3 創建 BroadcastReceiver? : ??接收鬧鐘觸發事件

public class AlarmReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 執行任務邏輯(如啟動服務、發送通知)Log.d("Alarm", "Triggered at exact time!");}
}

別忘了注冊 Receiver?

<receiver android:name=".AlarmReceiver" android:exported="false"/>

5.4 設置精確鬧鐘?

// 獲取 AlarmManager
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);// 創建 Intent 指向 BroadcastReceiver
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);// 設置觸發時間(例如 10 分鐘后)
long triggerTime = System.currentTimeMillis() + 10 * 60 * 1000;// 根據版本選擇方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, // 使用 UTC 時間并喚醒設備triggerTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}

5.5 設置了AlarmManager,如果系統時間變更了,是不是鬧鐘在現實世界響起的時間也會變 ?

  • 若用戶將系統時間??調快 1 小時??(從 9:00 改為 10:00),鬧鐘會??立即觸發??(因為系統時間已達到目標值)。
  • 若將系統時間??調慢 1 小時??(從 10:00 改為 9:00),鬧鐘會??延遲 1 小時觸發??(需等待系統時間再次達到 10:00)

可以監聽系統時間變化的廣播,然后更改鬧鐘

// 在 onResume() 中注冊
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(timeChangeReceiver, filter);// 在 onPause() 中注銷
unregisterReceiver(timeChangeReceiver);

5.6 STATE_DOZE和STATE_DOZE_SUSPEND,有什么區別 ?

在 Android 電源管理機制中,STATE_DOZESTATE_DOZE_SUSPEND 是兩種不同的休眠狀態,其核心區別在于系統資源限制的嚴格程度CPU活動狀態。以下是兩者的詳細對比:

6. STATE_DOZE 和 STATE_DOZE_SUSPEND

  • STATE_DOZE(Doze 模式)

    • 首次引入于 Android 6.0(Marshmallow),目的是在設備閑置時(未充電、屏幕關閉、靜止狀態)減少后臺活動。
    • 狀態描述:系統進入低功耗狀態,但CPU仍保持部分活動,周期性喚醒處理任務。
  • STATE_DOZE_SUSPEND(Doze 掛起模式)

    • 強化版省電機制,于 Android 9.0(Pie) 引入,作為 Doze 的深度擴展。
    • 狀態描述:系統進入更深度的休眠CPU 完全停止運行,僅保留最低限度的硬件喚醒能力(如傳感器)。

6.1 CPU 與任務執行機制**

  • STATE_DOZE

    • CPU 未完全停止,而是周期性喚醒(維護窗口)。
    • 維護窗口間隔:初始為每 30 分鐘喚醒一次,隨后間隔逐漸延長(如 1 小時、2 小時)。
    • 任務處理:在維護窗口內,系統允許應用執行延遲的任務(如同步、AlarmManager 鬧鐘)。
  • STATE_DOZE_SUSPEND

    • CPU 完全掛起,無周期性喚醒。
    • 任務凍結:所有后臺進程被強制暫停(通過 Linux cgroup 的 freezer 子系統),不再分配 CPU 時間片。
    • 喚醒條件:僅通過外部事件觸發(如用戶操作、高優先級鬧鐘 setAlarmClock())。

6.2 網絡與后臺資源訪問

  • STATE_DOZE

    • 網絡限制:禁止后臺應用訪問網絡,僅維護窗口內開放。
    • 部分豁免:高優先級 GCM 消息、短信/電話可臨時喚醒網絡。
  • STATE_DOZE_SUSPEND

    • 完全斷網:所有網絡訪問被禁止,包括 GCM 和短信(僅保留基礎通信服務如通話)。
    • 硬件限制:Wi-Fi/GPS 掃描、傳感器數據采集均暫停。

6.3 鬧鐘與任務調度行為

  • STATE_DOZE

    • 標準鬧鐘延遲setExact()setWindow() 的鬧鐘被推遲至下一個維護窗口。
    • 豁免鬧鐘setAndAllowWhileIdle()setExactAndAllowWhileIdle() 可在 Doze 下觸發(但受每分鐘 1 次的頻率限制)。
  • STATE_DOZE_SUSPEND

    • 所有鬧鐘凍結:包括 AllowWhileIdle 類型的鬧鐘,僅 setAlarmClock()(用戶可見的鬧鐘)可喚醒設備。
    • 任務調度失效:JobScheduler 和 WorkManager 任務被無限期推遲,直至退出 SUSPEND 狀態。

6.4 Wakelock 處理

  • STATE_DOZE

    • 部分屏蔽:普通 WakeLock 被忽略(如 PARTIAL_WAKE_LOCK),但高優先級服務(如媒體播放)可能被豁免。
  • STATE_DOZE_SUSPEND

    • 完全無效:所有 WakeLock 被強制釋放,無法阻止 CPU 掛起。

6.5 持續時間與退出機制

  • STATE_DOZE

    • 動態維護窗口:窗口間隔隨閑置時間延長而增加(30 分鐘 → 1 小時 → 數小時)。
    • 退出條件:屏幕點亮、設備移動或充電。
  • STATE_DOZE_SUSPEND

    • 持續掛起:無周期性窗口,直至外部事件喚醒。
    • 退出條件更嚴格:僅用戶交互(如按鍵)、setAlarmClock() 鬧鐘或充電可喚醒。

6.6 對比總結

特性STATE_DOZESTATE_DOZE_SUSPEND
CPU 狀態周期性喚醒(維護窗口)完全停止
網絡訪問僅維護窗口開放完全禁止
鬧鐘執行允許 AllowWhileIdle 類型setAlarmClock() 有效
任務調度維護窗口內執行完全凍結
Wakelock 有效性部分豁免全部釋放
退出條件移動/亮屏/充電僅用戶操作或高優先級鬧鐘
省電強度中度極端

6.7 適配建議

  1. 后臺任務
    • 使用 WorkManagerJobScheduler,其任務在 STATE_DOZE 的維護窗口自動執行,但 STATE_DOZE_SUSPEND 中仍會被凍結。
  2. 實時性需求
    • 關鍵任務(如鬧鐘)優先用 setAlarmClock()(用戶可見),或引導用戶將應用加入電池優化白名單。
  3. 網絡依賴
    • STATE_DOZE_SUSPEND 下網絡完全不可用,需通過高優先級 GCM 消息或短信喚醒設備(系統服務如電話/SMS 始終豁免)。
  4. 狀態檢測
    • 通過 PowerManager.isDeviceIdleMode() 檢測 Doze 狀態,但無法直接區分 SUSPEND(需依賴行為推斷)。

📌 核心結論
STATE_DOZE周期性喚醒的輕度休眠,適合延遲容忍的任務;
STATE_DOZE_SUSPENDCPU 完全停止的深度凍結,僅響應極高優先級事件。
開發者需針對兩者設計降級策略,確保關鍵功能在極端省電下仍可工作。

7. STATE_DOZE_SUSPEND狀態下設置setExactAndAllowWhileIdle有效嗎

在 Android 的 STATE_DOZE_SUSPEND(深度掛起模式)狀態下,setExactAndAllowWhileIdle() 是無效的。以下是具體原因和機制分析:


7.1 STATE_DOZE_SUSPEND 的特性

  • CPU 完全凍結
    此狀態下系統進入深度休眠,CPU 完全停止運行,所有后臺進程被強制暫停,僅保留基礎硬件喚醒能力(如高優先級鬧鐘或物理按鍵)。
  • 網絡與任務凍結
    所有網絡訪問被禁止,JobSchedulerWorkManager 等后臺任務被無限期推遲,標準鬧鐘和 AllowWhileIdle 類鬧鐘均被凍結。

7.2 setExactAndAllowWhileIdle() 的限制

  • 僅適用于普通 Doze 模式
    setExactAndAllowWhileIdle() 設計用于 STATE_DOZE(普通休眠),可在維護窗口外觸發(但受每分鐘 1 次的頻率限制)。但在 STATE_DOZE_SUSPEND 下,系統無周期性喚醒機制,導致該方法失效。
  • 深度省電下的喚醒條件
    僅以下事件可喚醒 STATE_DOZE_SUSPEND
    • 用戶主動操作(如點亮屏幕)
    • 高優先級鬧鐘 setAlarmClock()(系統會提前退出休眠并顯示通知)
    • 設備充電。

7.3 替代方案

若需在 STATE_DOZE_SUSPEND 下可靠觸發任務,需采用以下策略:

  1. setAlarmClock()
    • 用于用戶可見的精確鬧鐘(如鬧鐘應用),系統會強制退出休眠并顯示通知欄圖標。
    • 無需特殊權限,但用戶感知明顯。
  2. 引導用戶加入白名單
    • 用戶手動在 設置→電池優化 中將應用設為“未優化”,可部分豁免限制(非完全保障,廠商兼容性差異大)。
  3. 前臺服務(Foreground Service)
    • 通過持續通知欄服務維持進程活躍性,但需合理說明用途以避免被系統限制或用戶關閉。

7.4 總結:不同鬧鐘方法在 Doze 模式下的有效性

鬧鐘方法STATE_DOZE(普通休眠)STATE_DOZE_SUSPEND(深度掛起)
setExact() / setWindow()? 延遲至維護窗口? 完全凍結
setAndAllowWhileIdle()? 可觸發(精度低)? 無效
setExactAndAllowWhileIdle()? 可觸發(秒級誤差)? 無效
setAlarmClock()? 立即觸發? 強制喚醒(需用戶可見通知)

結論
STATE_DOZE_SUSPEND 下,setExactAndAllowWhileIdle() 無法觸發。若需極端省電模式下的可靠性,應優先使用 setAlarmClock() 或引導用戶設置白名單)。

8. 更多內容

有關WorkManager基礎的概念和使用,詳見 : Android WorkManager的概念和使用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/923612.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/923612.shtml
英文地址,請注明出處:http://en.pswp.cn/news/923612.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS 能耗監控與電池優化實戰:如何查看App耗電量、分析CPU、GPU內存使用、(uni-app iOS開發性能調試指南)

在 iOS 應用開發中&#xff0c;能耗與電池消耗是用戶最直觀的體驗指標。 即便功能完善&#xff0c;如果 App 存在以下問題&#xff1a; 電池掉電快、設備發熱嚴重&#xff1b;后臺任務執行過多&#xff1b;頁面渲染與文件操作引發 CPU/GPU 過載&#xff1b;日志或緩存導致頻繁 …

Git 本地分支推送多個遠程分支

方法一&#xff1a;一次性推送命令 命令格式&#xff1a; git push <遠程倉庫名> <本地分支引用>:<遠程分支名1> <本地分支引用>:<遠程分支名2> ...具體步驟&#xff1a; 確保你的代碼修改已經提交到了本地分支 git add . git commit -m "你…

抖音私信評論互動消息通知監聽自動獲取,通過qq機器人轉發到qq來通知

抖音私信評論互動消息通知監聽自動獲取&#xff0c;通過qq機器人轉發到qq來通知 如果不是抖音平臺&#xff0c;其他平臺也類似的&#xff0c;也可以實現&#xff0c;只是目前懶得寫了 本期視頻點贊過10個就開源代碼 有需要的人可以在視頻底下留言 需求反饋多的我可以實現

UVM驗證工具--gvim

目錄 gvim語法高亮 gvim支持git Linux環境自帶gvim工具&#xff0c;我們需要做如下設置&#xff1a; 支持UVM、SystemVerilog、verilog語法高亮支持git&#xff08;實時顯示對文件的修改&#xff09; gvim語法高亮 gvim支持git

MyBatis 從入門到精通(第二篇)—— 核心架構、配置解析與 Mapper 代理開發

在第一篇博客中&#xff0c;我們掌握了 MyBatis 的基礎概念與環境搭建&#xff0c;成功通過簡單查詢實現了數據持久化。但要真正用好 MyBatis&#xff0c;還需深入理解其 “內部工作原理” 與 “企業級開發規范”。本篇將聚焦三大核心&#xff1a;MyBatis 架構與核心類、全局配…

uniapp+<script setup lang=“ts“>單個時間格式轉換(format)

有問題的時間&#xff08;只示例&#xff0c;不是真實數據&#xff09;修改后的時間展示&#xff08;只示例&#xff0c;不是真實數據&#xff09;原代碼<view v-else-if"item?.payTime" class"order-info-item">支付時間&#xff1a;item?.payTim…

運維安全05,iptables規則保存與恢復

一&#xff1a;網絡安全1.1、昨日功能優化配置后引發的問題&#xff1a;配置iptables后防火墻起到了防護作用&#xff0c;但使用127.0.0.1訪問不了數據庫了[rootlocalhost /]# mysql -u admin -p -h 127.0.0.1 Enter password:思考&#xff1a;如果使用localhost可以訪問嗎&…

線性代數 · 矩陣 | 秩 / 行秩 / 列秩 / 計算方法

注&#xff1a;本文為 “線性代數 矩陣 | 秩” 相關合輯。 圖片清晰度受引文原圖所限。 略作重排&#xff0c;未全校去重。 如有內容異常&#xff0c;請看原文。 矩陣的秩及其應用 一、矩陣秩的基本概念 &#xff08;一&#xff09;k 階子式 設矩陣 A(aij)mnA (a_{ij})_{m…

Ajax-day2(圖書管理)-彈框顯示和隱藏

Bootstrap 彈框圖書管理-Bootsrap 彈框&#xff08;一&#xff09;屬性控制一、模板代碼二、彈框模板三、bootsrap 的顯示彈框屬性完整代碼&#xff08;二&#xff09;JS 控制一、模板代碼二、步驟圖書管理-Bootsrap 彈框 Bootstrap 框架渲染列表&#xff08;查&#xff09;新…

【Linux網絡】認識https

認識https一&#xff0c;概念鋪墊1.1 什么是加密&#xff1f;1.2 為什么要加密&#xff1f;1.3 加密的方式1.4 數據摘要&數據指紋二&#xff0c;認識https2.1 方案1-只使用對稱加密2.2 方案2-只使用非對稱加密2.3 方案3-雙方都使用非對稱加密2.4 方案4-非對稱加密對稱加密2…

OC-AFNetworking

文章目錄AFNetworking簡介問題&#x1f914;優化策略解決AFNetworking局限性使用單例進行網絡請求的優勢使用單例進行網絡請求的風險最優使用使用參數講解POST請求AFNetworking 簡介 這篇文章旨在實現使用AFNetworking設置一個集中的單通道網絡對象&#xff0c;該對象與MVC組建…

【數據結構】跳表

目錄 1.什么是跳表-skiplist 2.skiplist的效率如何保證&#xff1f; 3.skiplist的實現 3.1節點和成員設計 3.2查找實現 3.3前置節點查找 3.4插入實現 3.5刪除實現 3.6隨機層數 3.7完整代碼 4.skiplist跟平衡搜索樹和哈希表的對比 1.什么是跳表-skiplist skiplist是由…

html實現右上角有個圖標,鼠標移動到該位置出現手型,點擊會彈出登錄窗口。

寫了一段html代碼實現的效果&#xff1a;實現右上角有個圖標&#xff0c;鼠標移動到該位置出現手型&#xff0c;點擊會彈出登錄窗口。功能實現前端&#xff0c;沒有實現后端。<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF…

STM32G4 電流環閉環(二) 霍爾有感運行

目錄一、STM32G4 電流環閉環(二) 霍爾有感運行2. 霍爾有感運行附學習參考網址歡迎大家有問題評論交流 (* ^ ω ^)一、STM32G4 電流環閉環(二) 霍爾有感運行 2. 霍爾有感運行 文章使用的BLDC在定子側以互差120電角度的位置安裝三個霍爾元件Ha&#xff0c;Hb&#xff0c;Hc。當…

展示框選擇

好的&#xff0c;非常感謝您提供更詳細的項目情況。這是一個非常典型的父子組件通信場景。 根據您的新需求&#xff0c;我將對代碼進行重構&#xff1a; FaultSelect.vue (子組件): 這個組件現在將變得更加“純粹”。它只負責自身的下拉框邏輯&#xff0c;不關心外部按鈕&#…

第5課:上下文管理與狀態持久化

第5課:上下文管理與狀態持久化 課程目標 掌握上下文存儲和檢索策略 學習會話狀態管理 了解數據持久化方案 實踐實現上下文管理系統 課程內容 5.1 上下文管理基礎 什么是上下文管理? 上下文管理是Agent系統中維護和利用歷史信息的能力,包括: 對話歷史:用戶與Agent的交互…

計算機畢業設計 基于大數據技術的醫療數據分析與研究 Python 大數據畢業設計 Hadoop畢業設計選題【附源碼+文檔報告+安裝調試】

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python、大數據、人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&…

K8S集群管理(2)

目錄 1.什么是Pod的根容器&#xff1f; 2.解釋Pod的生命周期。 3.Init類型容器有什么特點&#xff0c;主要用途&#xff1f; 4.Sidecar類型容器和Init容器的區別在哪&#xff1f; 5.什么是靜態Pod&#xff1f; 6.說明K8s控制器的作用&#xff1f; 7.什么是ReplicaSet&#xff0…

視頻全模態referring分割:Ref-AVS: Refer and Segment Objects in Audio-Visual Scenes

一、TL&#xff1b;DR 為什么要做&#xff1a;傳統的referring分割無法使用音頻模態&#xff0c;本文提出Reference audio-visual Segmentation本文怎么做&#xff1a;構建首個 Ref-AVS 基準數據集通過充分利用多模態提示&#xff0c;將音頻信息通過和文本融合作為載體&#x…

A股大盤數據-20250916分析

&#x1f4ca; 一、大盤數據深度分析1.1 &#x1f9ee; 市場活躍度與資金流向總成交額&#xff1a;滬深京合計約 2.37萬億元&#xff0c;市場交投活躍&#xff0c;深市成交&#xff08;13516.4億&#xff09;明顯高于滬市&#xff08;9897.9億&#xff09;&#xff0c;顯示中小…