使用 Wake Lock 可能會影響裝置效能。如需使用喚醒鎖定,請務必正確操作。本文將介紹幾項最佳做法,協助您避開常見的喚醒鎖定陷阱。
正確命名 Wake Lock
建議您在 Wake Lock 標記中加入封包、類別或方法名稱。這樣一來,如果發生錯誤,就能更輕鬆地在原始碼中找出建立喚醒鎖的位置。以下提供幾項額外的訣竅:
- 請勿在名稱裡面填寫個人識別資訊 (PII),例如電子郵件地址等。如果裝置在 Wake Lock 標記中偵測到 PII,系統會記錄
_UNKNOWN
,而不是您指定的標記。 - 請勿藉由程式輔助方式產生類別或方法名稱,例如藉由呼叫
getName()
產生名稱等。如果您嘗試以程式輔助方式取得名稱,名稱可能會遭到 Proguard 等工具模糊處理。請改用硬式編碼字串。 - 請勿將計數器或專用 ID 加到 Wake Lock 標籤,建立喚醒鎖定的程式碼每次執行時,都應使用相同的標記。這個做法可讓系統彙整每個方法的喚醒鎖定使用情形。
確認應用程式顯示在前景
Wake Lock 啟用時,裝置會耗電。裝置使用者應瞭解這項操作。因此,如果您使用 Wake Lock,應向使用者顯示通知。在實務上,這表示您應在前景服務中取得並保留喚醒鎖定。前景服務必須顯示通知。
如果前景服務不適合您的應用程式,您可能也不該使用喚醒鎖定。如要瞭解在應用程式未處於前景時執行工作的其他方法,請參閱「選擇合適的 API,讓裝置保持喚醒狀態」說明文件。
保持簡單的邏輯
確保獲取和釋放 Wake Lock 時,盡可能使用簡單的邏輯。如果 Wake Lock 邏輯和複雜的狀態機器、逾時、執行程式集區或回呼事件有關,那麼一旦這個邏輯裡有任何不明顯的錯誤,就可能會導致 Wake Lock 保留時間超出預期。這種錯誤的診斷和偵錯作業相當困難。
確認 Wake Lock 一律會釋放
如果您使用 Wake Lock,請務必確保獲取的每個 Wake Lock 都已正確釋放。這看似簡單,但其實不然。舉例來說,下列程式碼有問題:
Kotlin
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
acquire()
doTheWork() // can potentially throw MyException
release() // does not run if an exception is thrown
}
}
Java
void doSomethingAndRelease() throws MyException {
wakeLock.acquire();
doTheWork(); // can potentially throw MyException
wakeLock.release(); // does not run if an exception is thrown
}
這裡的問題是,方法 doTheWork()
可能會擲回例外狀況 MyException
。如果發生這種情況,doSomethingAndRelease()
方法會向外傳播例外狀況,且永遠不會到達 release()
呼叫。結果是取得喚醒鎖定,但未釋放,這非常糟糕。
在修正後的程式碼中,即使擲回例外狀況,doSomethingAndRelease()
也會確保釋出喚醒鎖定:
Kotlin
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
try {
acquire()
doTheWork()
} finally {
release()
}
}
}
Java
void doSomethingAndRelease() throws MyException {
try {
wakeLock.acquire();
doTheWork();
} finally {
wakeLock.release();
}
}