Best Practices für Wakelocks beachten

Die Verwendung eines Wake Locks kann die Geräteleistung beeinträchtigen. Wenn Sie einen Wake Lock verwenden müssen, ist es wichtig, dass Sie dies richtig tun. In diesem Dokument werden einige Best Practices beschrieben, mit denen Sie häufige Fehler bei der Verwendung von Wake Locks vermeiden können.

Wakelock richtig benennen

Wir empfehlen, den Paket-, Klassen- oder Methodennamen in das Wake Lock-Tag aufzunehmen. So lässt sich bei einem Fehler leichter die Stelle im Quellcode finden, an der der Wake Lock erstellt wurde. Hier einige zusätzliche Tipps:

  • Lassen Sie alle personenidentifizierbaren Informationen wie E‑Mail-Adressen im Namen weg. Wenn das Gerät personenbezogene Daten im Wake Lock-Tag erkennt, wird _UNKNOWN anstelle des von Ihnen angegebenen Tags protokolliert.
  • Rufen Sie den Klassen- oder Methodennamen nicht programmatisch ab, z. B. durch Aufrufen von getName(). Wenn Sie versuchen, den Namen programmatisch abzurufen, wird er möglicherweise durch Tools wie Proguard verschleiert. Verwenden Sie stattdessen einen fest codierten String.
  • Fügen Sie den Wake Lock-Tags keinen Zähler oder keine eindeutigen Kennungen hinzu. Der Code, der einen Wake Lock erstellt, sollte bei jeder Ausführung dasselbe Tag verwenden. So kann das System die Wake Lock-Nutzung der einzelnen Methoden zusammenfassen.

Ihre App muss im Vordergrund sichtbar sein

Wenn ein Wake Lock aktiv ist, verbraucht das Gerät Strom. Der Nutzer des Geräts sollte darüber informiert werden. Wenn Sie einen Wake Lock verwenden, sollten Sie dem Nutzer daher eine Benachrichtigung anzeigen. In der Praxis bedeutet das, dass Sie den Wakelock in einem Dienst im Vordergrund abrufen und halten sollten. Vordergrunddienste sind erforderlich, um eine Benachrichtigung anzuzeigen.

Wenn ein Dienst im Vordergrund nicht die richtige Wahl für Ihre App ist, sollten Sie wahrscheinlich auch keine Wake Locks verwenden. In der Dokumentation Die richtige API auswählen, um das Gerät aktiv zu halten finden Sie weitere Möglichkeiten, Aufgaben auszuführen, wenn Ihre App nicht im Vordergrund ist.

Einfache Logik verwenden

Die Logik zum Erwerben und Freigeben von Wake Locks sollte so einfach wie möglich sein. Wenn Ihre Wake Lock-Logik an komplexe Zustandsautomaten, Zeitüberschreitungen, Executor-Pools oder Callback-Ereignisse gebunden ist, kann jeder subtile Fehler in dieser Logik dazu führen, dass das Wake Lock länger als erwartet gehalten wird. Diese Fehler sind schwer zu diagnostizieren und zu beheben.

Prüfen, ob die Wake Lock-Sperre immer freigegeben wird

Wenn Sie einen Wake Lock verwenden, müssen Sie darauf achten, dass jeder Wake Lock, den Sie erhalten, ordnungsgemäß freigegeben wird. Das ist nicht immer so einfach, wie es klingt. Der folgende Code enthält beispielsweise ein Problem:

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
}

Das Problem besteht darin, dass die Methode doTheWork() die Ausnahme MyException auslösen kann. Wenn dies der Fall ist, gibt die Methode doSomethingAndRelease() die Ausnahme nach außen weiter und sie erreicht den release()-Aufruf nie. Das Ergebnis ist, dass der Wake Lock zwar aktiviert, aber nicht deaktiviert wird, was sehr schlecht ist.

Im korrigierten Code wird durch doSomethingAndRelease() dafür gesorgt, dass der Wake Lock auch dann freigegeben wird, wenn eine Ausnahme ausgelöst wird:

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