Stosowanie sprawdzonych metod dotyczących blokady aktywacji

Używanie blokady uśpienia może pogorszyć wydajność urządzenia. Jeśli musisz użyć blokady uśpienia, ważne jest, aby zrobić to prawidłowo. W tym dokumencie znajdziesz sprawdzone metody, które pomogą Ci uniknąć typowych problemów z blokadami uśpienia.

Prawidłowe nazwanie blokady uśpienia

Zalecamy, aby w tagu blokady uśpienia podać nazwę pakietu, klasy lub metody. Dzięki temu w razie błędu łatwiej będzie znaleźć w kodzie źródłowym miejsce, w którym utworzono blokadę uśpienia. Oto kilka dodatkowych wskazówek:

  • Nie podawaj w nazwie żadnych informacji umożliwiających identyfikację, takich jak adres e-mail. Jeśli urządzenie wykryje w tagu blokady uśpienia informacje umożliwiające identyfikację, zapisze _UNKNOWN zamiast podanego przez Ciebie tagu.
  • Nie pobieraj nazwy klasy ani metody automatycznie, np. przez wywołanie getName(). Jeśli spróbujesz uzyskać nazwę automatycznie, może ona zostać zaciemniona przez narzędzia takie jak Proguard. Zamiast tego użyj ciągu znaków zakodowanego na stałe.
  • Nie dodawaj do tagów blokady uśpienia licznika ani unikalnych identyfikatorów. Kod, który tworzy blokadę uśpienia, powinien za każdym razem używać tego samego tagu. Dzięki temu system może agregować wykorzystanie blokady uśpienia przez każdą metodę.

Upewnij się, że aplikacja jest widoczna na pierwszym planie.

Gdy blokada uśpienia jest aktywna, urządzenie zużywa energię. Użytkownik urządzenia powinien wiedzieć, że tak się dzieje. Dlatego jeśli używasz blokady uśpienia, musisz wyświetlić użytkownikowi powiadomienie. W praktyce oznacza to, że blokadę uśpienia należy uzyskać i utrzymać w usłudze na pierwszym planie. Usługi działające na pierwszym planie muszą wyświetlać powiadomienie.

Jeśli usługa na pierwszym planie nie jest odpowiednim wyborem dla Twojej aplikacji, prawdopodobnie nie powinna ona też używać blokady uśpienia. W dokumentacji dotyczącej wyboru odpowiedniego interfejsu API, który zapobiega przechodzeniu urządzenia w stan uśpienia, znajdziesz inne sposoby wykonywania zadań, gdy aplikacja nie działa na pierwszym planie.

Uproszczenie logiki

Zadbaj o to, aby logika wywoływania i zwalniania blokad uśpienia była jak najprostsza. Gdy logika blokady uśpienia jest powiązana ze złożonymi maszynami stanów, limitami czasu, pulami wykonawców lub zdarzeniami wywołania zwrotnego, każdy drobny błąd w tej logice może spowodować, że blokada uśpienia będzie utrzymywana dłużej niż oczekiwano. Te błędy są trudne do zdiagnozowania i naprawienia.

Sprawdzanie, czy blokada uśpienia jest zawsze zwalniana

Jeśli używasz blokady uśpienia, musisz zadbać o to, aby każda wywołana blokada została prawidłowo zwolniona. Nie zawsze jest to takie proste, jak się wydaje. Na przykład ten kod zawiera błąd:

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
}

Problem polega na tym, że metoda doTheWork() może zwrócić wyjątek MyException. Jeśli tak, metoda doSomethingAndRelease() przekazuje wyjątek na zewnątrz i nigdy nie dociera do wywołania release(). W rezultacie blokada uśpienia jest uzyskiwana, ale nie jest zwalniana, co jest bardzo niekorzystne.

W poprawionym kodzie doSomethingAndRelease() zapewnia zwolnienie blokady uśpienia nawet w przypadku zgłoszenia wyjątku:

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