使用 Wake Lock 可能會影響裝置效能。如果需要使用喚醒鎖定功能,請務必正確使用。本文將說明一些最佳做法,協助您避免常見的喚醒鎖定陷阱。
正確命名 Wake Lock
建議您在 Wake Lock 標記中加入封包、類別或方法名稱。這樣一來,如果發生錯誤,您就能更輕鬆地在原始碼中找出建立喚醒鎖定的位置。以下提供幾項額外的訣竅:
- 請勿在名稱裡面填寫個人識別資訊 (PII),例如電子郵件地址等。如果裝置在 Wake Lock 標記中偵測到 PII,就會記錄
_UNKNOWN
,而不是您指定的標記。 - 請勿藉由程式輔助方式產生類別或方法名稱,例如藉由呼叫
getName()
產生名稱等。如果您嘗試以程式輔助方式取得名稱,可能會遭到 Proguard 等工具模糊處理。請改用硬式編碼字串。 - 請勿將計數器或專用 ID 加到 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();
}
}