找出並改善喚醒鎖定應用實例

本文可協助您找出並最佳化應用程式中的 Wake Lock 用途,並指出是否有其他程式庫或系統 API 取得與此用途相關聯的 Wake Lock。由於這些 Wake Lock 可歸因於您的應用程式,因此可能很難找出有問題的 Wake Lock 來源。如果 API 使用方式不正確,即使您並未明確取得 Wake Lock,應用程式仍可能因 Wake Lock 使用過度而遭到標記。

本文列出使用 Wake Lock 偵錯工具或Android Vitals 報表時,可能遇到的常見 Wake Lock 名稱。這些名稱可能來自程式庫或系統 API,也可能經過模糊處理。使用偵錯工具找出行為不當的 Wake Lock,然後在本文中搜尋 Wake Lock 名稱,即可判斷可能造成問題的 API,並找到最佳化使用方式的建議。

本文概述取得 Wake Lock 的常見用途,詳細說明各種 API 和程式庫使用的 Wake Lock 名稱,並提供最佳化及減少 Wake Lock 使用量的建議和最佳做法。

AlarmManager

AlarmManager 會取得 Wake Lock,並將其歸因於呼叫應用程式。AlarmManager 會在鬧鐘響起時取得 Wake Lock,並在鬧鐘廣播的 onReceive() 方法執行完畢時釋放鎖定。

Wake Lock 名稱

AlarmManager 會建立名為 *alarm* 的 Wake Lock。(星號是 Wake Lock 名稱的一部分,不代表萬用字元)。

建議

建議採取下列做法,將鬧鐘行為調整至最佳狀態:

  • 請參閱「選擇鬧鐘類型」,決定要使用不精確鬧鐘或精確鬧鐘。如果鬧鐘不需要精確,請使用不精確鬧鐘,讓系統在排程時更有彈性,進而延長電池續航力。
  • 請留意系統設定的鬧鐘配額,並在設計應用程式時遵守這些限制。
  • 避免在 onReceive() 方法中執行冗長的工作,並在鬧鐘響起後需要額外處理時,排定工作站。

音訊和媒體

媒體 API 可以在錄製或播放音訊時取得 Wake Lock。Wake Lock 會歸因於呼叫應用程式。

Wake Lock 名稱

媒體 API 會取得各種名稱開頭為 Audio 的 Wake Lock:

  • AudioBitPerfect:用於無損 USB 音訊播放。
  • AudioDirectOut:用於在電視或特殊裝置上播放無損音訊。
  • AudioDup:透過藍牙或 USB 連線時,用於播放通知。
  • AudioIn:在攝影機模式下,當麥克風啟用時,用於擷取音訊。
  • AudioMix:用於在一般裝置上播放音訊。
  • AudioOffload:用於長時間播放音樂,適用於支援此模式的應用程式。
  • AudioSpatial:用於在支援空間音訊的裝置上播放多聲道電影或音樂音訊。
  • AudioUnknown:不適用於其他情況時使用。
  • MmapCapture:用於低延遲音訊擷取。
  • MmapPlayback:用於低延遲播放,例如遊戲或專業音訊應用程式。

建議

建議採取下列做法:

  • 請勿宣告開頭為 Audio 的 Wake Lock 名稱。
  • 如果您使用媒體 API,就不需要直接取得 Wake Lock,可以依賴 API 為您取得必要的 Wake Lock。
  • 使用媒體 API 時,請在不再需要時結束媒體工作階段和相關聯的前景服務。

藍牙

平台藍牙 API 主要在藍牙動作發生時保留核心 Wake Lock,這不屬於應用程式。

建議

  • 使用配對裝置配對功能配對藍牙裝置,避免在藍牙配對期間取得手動 Wake Lock。
  • 請參閱在背景通訊指南,瞭解如何在背景進行藍牙通訊。
  • 如果延遲通訊不會影響使用者,通常使用 WorkManager 就足夠。如果認為有必要手動設定 Wake Lock,請只在藍牙活動或處理活動資料期間保留 Wake Lock。

裝置感應器

追蹤裝置感應器資料 (例如步數、加速計或陀螺儀資料) 的方法有很多種。

在 Wear OS 上,使用 Wear 健康照護服務擷取裝置資料,例如海拔高度、心率和移動距離。

如果資料是由其他應用程式收集,您可以將 健康資料同步 與 WorkManager 搭配使用,定期擷取資料。

如要追蹤步數或移動距離的變化,可以使用行動裝置上的 Recording API,並搭配 WorkManager 定期擷取資料。如要存取歷來步數資料 (例如每日步數總計,或過去 6 小時內的步數),「健康資料同步」也支援在搭載 Android 14 以上版本的裝置上追蹤步數。

在某些情況下,可能需要使用 SensorManager 追蹤自訂裝置感應器。除非感應器是喚醒感應器 (可使用 isWakeUpSensor API 識別),否則 SensorManager 不會代表應用程式取得 Wake Lock。

建議

使用感應器以高取樣率記錄資料,可能會大幅消耗電池電力。以下是減少電池耗電量和 Wake Lock 使用量的建議:

  • 如要追蹤步數或移動距離,請使用 Recording API,以高效的方式記錄資料。如果裝置搭載 Android 14 以上版本,建議使用 Health Connect 存取裝置歷來資料和匯總步數。
  • 如要在 Wear OS 上被動追蹤感應器,請使用 Wear 健康照護服務,盡可能減少電池用量。
  • 向 SensorManager 註冊感應器時,請定義超過 30 秒的 maxReportLatencyUs,以便使用感應器批次處理邏輯,並減少應用程式收到的中斷次數。當裝置隨後因其他觸發條件 (例如使用者互動、位置擷取或排定的工作) 而喚醒時,系統會立即分派快取的感應器資料。
  • 如果應用程式需要位置和感應器資料,請同步擷取及處理事件。將感應器讀數合併到系統為位置更新通知保留的短暫 Wake Lock,即可避免需要 Wake Lock 讓 CPU 保持喚醒狀態。使用 worker 或短時間 Wake Lock,處理這類合併資料的上傳和處理作業。

Firebase 雲端通訊 (FCM)

將 Firebase 雲端通訊 (FCM) 廣播傳送至應用程式時,系統會取得 Wake Lock。FCM 廣播 onMessageReceived() 方法執行完畢後,系統就會釋放 Wake Lock。

Wake Lock 名稱

裝置收到 FCM 訊息時,會保留短暫的 Wake Lock,名稱為 GOOGLE_C2DM,在 Android 16 以上版本中,Wake Lock 名稱為 GCM_MESSAGE。

建議

建議您採取下列做法,將 FCM 行為調整至最佳狀態:

  • 最佳化 FCM 傳送頻率。
  • 除非訊息確實需要立即傳送,否則請勿使用高優先順序 FCM。
  • 請盡快完成 onMessageReceived() 方法,或在需要額外處理時,排定 worker 繼續執行工作。詳情請參閱 Firebase 指南。

JobScheduler

JobScheduler 工作在背景執行工作時,會取得 Wake Lock。Wake Lock 會歸因於建立 worker 的應用程式。

Wake Lock 名稱

JobScheduler 取得的 Wake Lock 名稱取決於執行的 Android 系統版本和工作目的。

角括號括住的項目是變數。舉例來說,「<package_name>」是應用程式套件的名稱,而非文字 <package name>。不過,*job* 是含有星號的字元序列 *job*,星號並非做為萬用字元使用。

Android 15 以下版本

使用者啟動的工作會建立 Wake Lock,名稱格式如下:

*job*u/@<name_space>@/<package_name>/<classname>

其他工作則使用以下模式:

*job*/@<name_space>@/<package_name>/<classname>
Android 16 QPR2 以上版本

使用者啟動的工作會建立 Wake Lock,名稱格式如下:

*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

加急作業會使用以下模式:

*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

一般工作使用以下模式:

*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
範例

假設有一個加急作業,命名空間為 backup,追蹤標記為 started。套件名稱為 com.example.app,建立工作的類別為 com.backup.BackupFileService。

在搭載 Android 15 以下版本的裝置上,Wake Lock 的名稱如下:

*job*/@backup@/com.example.app/com.backup.BackupFileService

在搭載 Android 16 QPR2 以上版本的裝置上,Wake Lock 的名稱如下:

*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService

建議

  • 請勿針對使用者啟動的下載/ 上傳用途,手動取得 Wake Lock。請改用 User-Initiated Data Transfer (UIDT) API。這是使用者啟動的長時間資料移轉工作指定路徑。
  • 如果您發現 JobScheduler 建立的 Wake Lock 具有高 Wake Lock 用量,可能是因為您未正確設定工作,導致工作在某些情況下無法完成。建議您分析工作停止原因,特別是經常看到 STOP_REASON_TIMEOUT 時。
  • 檢查 JobScheduler 任務的使用情形。特別是請按照我們的指南,針對工作排程 API 最佳化電池用量。

位置

LocationManager 和 FusedLocationProviderClient 會使用 Wake Lock 取得及提供裝置位置資訊。Wake Lock 會歸因於呼叫這些 API 的應用程式。

Wake Lock 名稱

定位服務會使用下列名稱:

  • CollectionLib-SigCollector
  • NetworkLocationLocator
  • NetworkLocationScanner
  • NlpCollectorWakeLock
  • NlpWakeLock
  • *location*

建議

  • 請參閱最佳化位置資訊使用方式指南。建議您實作逾時機制、批次處理位置要求,或使用被動位置資訊更新。
  • 請避免為了快取位置資料而取得個別的連續 Wake Lock,因為這是多餘的,應予以移除。使用 FusedLocationProvider 或 LocationManager API 要求位置更新通知時,系統會在位置事件回呼期間自動觸發裝置喚醒。請改為將位置事件儲存在記憶體或儲存空間中,並使用 WorkManager 定期處理位置事件。

遠端訊息

本節將討論涉及遠端訊息傳遞的情境,在這些情境中,應用程式可能需要維持連線,或回應其他裝置的事件,這可能會影響 Wake Lock 的使用。常見用途包括:

  • 影像或聲音監控隨附應用程式,需要監控透過區域網路連線的外部裝置上發生的事件。
  • 與電腦版維持網路通訊端連線的訊息應用程式。

在這些遠端訊息傳遞情境中,大多數喚醒作業都是核心 Wake Lock。由於核心 Wake Lock 不會歸因於應用程式,因此這裡不會列出相關聯的 Wake Lock 名稱。

建議

  • 如果網路事件可在伺服器端處理,請使用 FCM 接收用戶端資訊。如果需要額外處理 FCM 資料,您可以選擇排定快速 worker。
  • 如果必須使用通訊端連線在用戶端處理事件,則不需要 Wake Lock 即可監聽事件中斷。當資料封包到達 Wi-Fi 或手機無線電時,無線電硬體會以核心 Wake Lock 的形式觸發中斷。接著,您可以選擇排定工作站或取得 Wake Lock 來處理資料。
  • 舉例來說,如果您使用 ktor-network 監聽網路通訊端上的資料封包,則只有在封包傳送至用戶端時,才應取得 Wake Lock。

WorkManager

WorkManager worker 在背景執行工作時,會取得 Wake Lock。Wake Lock 會歸因於建立 worker 的應用程式。

Wake Lock 名稱

WorkManager 取得的 Wake Lock 名稱取決於執行的 Android 系統版本。

Android 15 以下版本

WorkManager 工作會建立 Wake Lock,名稱格式如下:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
Android 16 QPR2 以上版本

急件工作會建立 Wake Lock,名稱格式如下:

*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

一般工作的模式如下:

*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

根據預設,<trace_tag> 是 worker 名稱。

範例

假設有名為 BackupFileWorker 的加急 worker。套件名稱為 com.example.app。

在搭載 Android 15 以下版本的裝置上,Wake Lock 的名稱如下:

*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

在搭載 Android 16 QPR2 以上版本並使用 WorkManager 2.10.0+ 的裝置上,Wake Lock 的名稱如下:

*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

建議

  • 請將 WorkManager 升級至最新穩定版,以便在 Android 16 QPR2 以上版本中,取得更詳細的 Wake Lock 標記。
  • 檢查 WorkManager worker 的使用情形。特別是,請確認它遵循我們的最佳化電池使用量以排程工作 API 指南。如要在 Android 16 QPR2 以上版本中,讓 Wake Lock 標記更詳細,請在 worker 上使用 setTraceTag 方法,新增更多偵錯資訊,例如排定 worker 的類別。
  • 如果發現 WorkManager 建立的 Wake Lock 耗用大量資源,可能是因為 Worker 設定錯誤,導致在特定情況下無法完成。建議您分析工作站停止原因,特別是 STOP_REASON_TIMEOUT 發生頻率偏高時。
  • 除了記錄 worker 停止原因外,請參閱偵錯 worker 說明文件。此外,建議您收集並分析系統追蹤記錄,瞭解 Wake Lock 的取得和釋放時間。

_UNKNOWN

如果偵錯工具認為 Wake Lock 名稱包含個人識別資訊 (PII),就不會顯示實際的 Wake Lock 名稱。而是將 Wake Lock 標示為 _UNKNOWN。舉例來說,如果 Wake Lock 名稱包含電子郵件地址,工具可能會執行這項操作。

建議

遵循 Wake Lock 命名最佳做法,避免在 Wake Lock 名稱中使用 PII。如果發現名為 _UNKNOWN 的 Wake Lock 歸因於您的應用程式,請嘗試找出該 Wake Lock,並為其指定其他名稱。