遵循喚醒鎖定功能的最佳做法

使用 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();
    }
}