Określanie i optymalizowanie przypadków użycia blokady wybudzania

Ten dokument pomoże Ci zidentyfikować i zoptymalizować przypadki użycia blokady uśpienia w aplikacji, a także sprawdzić, czy istnieją blokady uśpienia uzyskane przez inne biblioteki lub interfejsy API systemu powiązane z danym przypadkiem użycia. Ponieważ te blokady uśpienia można przypisać do Twojej aplikacji, określenie źródła problematycznej blokady uśpienia może być trudne. Nieprawidłowe użycie interfejsu API może spowodować, że aplikacja zostanie oznaczona jako nadmiernie korzystająca z blokad uśpienia, nawet jeśli nie uzyskujesz ich bezpośrednio.

W tym dokumencie znajdziesz listę typowych nazw blokad uśpienia, które możesz zobaczyć podczas korzystania z narzędzi do debugowania blokad uśpienia lub w raportach z Vitals. Nazwy te mogą pochodzić z biblioteki lub interfejsu API systemu albo mogą być zaciemnione. Za pomocą narzędzi do debugowania możesz zidentyfikować nieprawidłowo działające blokady uśpienia, a następnie wyszukać nazwę blokady uśpienia w tym dokumencie, aby dowiedzieć się, który interfejs API może powodować problem, i znaleźć zalecenia dotyczące optymalizacji jego użycia.

W tym dokumencie opisujemy typowe przypadki użycia blokad uśpienia, podajemy nazwy blokad uśpienia używane przez różne interfejsy API i biblioteki oraz przedstawiamy zalecenia i sprawdzone metody optymalizacji i ograniczania użycia blokad uśpienia.

AlarmManager

AlarmManager uzyskuje blokady uśpienia i przypisuje je do aplikacji wywołującej. AlarmManager uzyskuje blokadę uśpienia, gdy włączy się alarm, i zwalnia ją, gdy metoda onReceive() transmisji alarmu zakończy działanie.

Nazwy blokad uśpienia

AlarmManager tworzy blokady uśpienia o nazwie *alarm*. (Gwiazdki są częścią nazwy blokady uśpienia, nie są symbolami wieloznacznymi).

Rekomendacja

Aby zoptymalizować działanie alarmów, zalecamy stosowanie tych sprawdzonych metod:

  • Aby wybrać alarm nieprecyzyjny lub precyzyjny, zapoznaj się z sekcją Wybieranie typu alarmu. Jeśli alarm nie musi być precyzyjny, użyj alarmów nieprecyzyjnych, aby zapewnić systemowi większą elastyczność w planowaniu, co może wydłużyć czas pracy na baterii.
  • Pamiętaj o narzuconych przez system limitach alarmów i zaprojektuj aplikację tak, aby ich nie przekraczała.
  • Unikaj wykonywania długotrwałych zadań w metodzie onReceive() i zaplanuj instancje robocze, jeśli po alarmie wymagane jest dodatkowe przetwarzanie.

Dźwięk i multimedia

Interfejsy API multimediów mogą uzyskiwać blokady uśpienia podczas nagrywania lub odtwarzania dźwięku. Blokady uśpienia są przypisywane do aplikacji wywołującej.

Nazwy blokad uśpienia

Interfejsy API multimediów uzyskują blokady uśpienia o różnych nazwach, które zaczynają się od Audio:

  • AudioBitPerfect: służy do bezstratnego odtwarzania dźwięku przez USB.
  • AudioDirectOut: służy do odtwarzania dźwięku bezstratnego na telewizorze lub specjalnym urządzeniu.
  • AudioDup: służy do odtwarzania powiadomień po połączeniu przez Bluetooth lub USB.
  • AudioIn: służy do nagrywania dźwięku w trybie kamery, gdy mikrofon jest aktywny.
  • AudioMix: służy do odtwarzania dźwięku na zwykłym urządzeniu.
  • AudioOffload: służy do długotrwałego odtwarzania tylko muzyki w aplikacjach, które obsługują ten tryb.
  • AudioSpatial: służy do odtwarzania wielokanałowego dźwięku z filmu lub muzyki na urządzeniach, które obsługują dźwięk przestrzenny.
  • AudioUnknown: używana, gdy inne sytuacje nie mają zastosowania.
  • MmapCapture: służy do nagrywania dźwięku z niskim opóźnieniem.
  • MmapPlayback: służy do odtwarzania z niskim opóźnieniem, np. w przypadku gier lub profesjonalnych aplikacji audio.

Rekomendacja

Zalecamy stosowanie tych sprawdzonych metod:

  • Nie deklaruj nazw blokad uśpienia, które zaczynają się od Audio.
  • Jeśli korzystasz z interfejsów API multimediów, nie musisz bezpośrednio uzyskiwać blokad uśpienia. Możesz polegać na interfejsach API, które uzyskają niezbędne blokady.
  • Gdy korzystasz z interfejsów Media API, kończ sesje multimedialne i powiązane z nimi usługi na pierwszym planie, jeśli nie są już potrzebne.

Bluetooth

Interfejsy API Bluetooth platformy mają głównie blokady uśpienia jądra podczas wykonywania działań Bluetooth, które nie są przypisane do aplikacji.

Rekomendacja

  • Użyj parowania urządzenia towarzyszącego, aby sparować urządzenia Bluetooth i uniknąć ręcznego blokowania uśpienia podczas parowania Bluetooth.
  • Aby dowiedzieć się, jak komunikować się przez Bluetooth w tle, zapoznaj się ze wskazówkami dotyczącymi komunikacji w tle.
  • Jeśli opóźnienie komunikacji nie ma wpływu na użytkownika, często wystarczy użyć WorkManager. Jeśli ręczne blokowanie uśpienia jest konieczne, utrzymuj blokadę uśpienia tylko na czas działania Bluetootha lub przetwarzania danych o aktywności.

Czujniki urządzenia

Istnieje kilka metod śledzenia danych z czujników urządzenia, takich jak liczba kroków, dane z akcelerometru czy żyroskopu.

W Wear OS używaj funkcji dotyczących zdrowia w systemie Wear OS, aby pobierać z urządzenia dane takie, jak wysokość nad poziomem morza, tętno i przebyta odległość.

Jeśli dane są zbierane przez inne aplikacje, możesz używać Health Connect w połączeniu z biblioteką WorkManager, aby okresowo pobierać dane.

W scenariuszach takich jak śledzenie różnicy w liczbie kroków lub przebytej odległości możesz używać interfejsu Recording API na urządzeniach mobilnych w połączeniu z biblioteką WorkManager, aby okresowo pobierać dane. Aby uzyskać dostęp do historycznych danych o krokach (np. dziennej liczby kroków lub liczby kroków w ciągu ostatnich 6 godzin), Health Connect obsługuje też śledzenie liczby kroków na urządzeniu w przypadku urządzeń z Androidem 14 lub nowszym.

W niektórych sytuacjach może być potrzebne śledzenie danych z czujników urządzenia za pomocą funkcji SensorManager. SensorManager nie uzyskuje blokad uśpienia w imieniu aplikacji, chyba że czujnik jest czujnikiem wybudzania, który można zidentyfikować za pomocą interfejsu isWakeUpSensor API.

Rekomendacja

Korzystanie z czujników do rejestrowania danych z wysoką częstotliwością próbkowania może znacznie wyczerpywać baterię. Oto rekomendacje, które pomogą zmniejszyć zużycie baterii i wykorzystanie blokady uśpienia:

  • Jeśli śledzisz liczbę kroków lub przebytą odległość, użyj interfejsu Recording API, aby rejestrować dane w sposób oszczędzający baterię. W przypadku urządzeń z Androidem 14 lub nowszym rozważ użycie Health Connect, aby uzyskać dostęp do danych historycznych urządzenia i zagregowanej liczby kroków.
  • W przypadku pasywnego śledzenia danych z czujników Wear OS używaj funkcji dotyczących zdrowia w Wear OS, aby zoptymalizować zużycie baterii.
  • Podczas rejestrowania czujnika za pomocą SensorManager zdefiniuj parametr maxReportLatencyUs na wartość większą niż 30 sekund, aby używać logiki grupowania danych z czujników i zmniejszyć liczbę przerwań, które otrzymuje aplikacja. Gdy urządzenie zostanie następnie wybudzone przez inny aktywator, np. interakcję użytkownika, pobranie lokalizacji lub zaplanowane zadanie, system natychmiast wyśle dane z czujnika zapisane w pamięci podręcznej.
  • Jeśli aplikacja wymaga zarówno danych o lokalizacji, jak i danych z czujnika, zsynchronizuj pobieranie i przetwarzanie zdarzeń. Dzięki połączeniu odczytów czujników z krótką blokadą uśpienia, którą system utrzymuje na potrzeby informacji o zmianie lokalizacji, nie potrzebujesz blokady uśpienia, aby utrzymać procesor w stanie aktywności. Do obsługi przesyłania i przetwarzania tych połączonych danych użyj instancji roboczej lub krótkotrwałej blokady uśpienia.

Komunikacja w chmurze Firebase (FCM)

Blokada uśpienia jest uzyskiwana podczas dostarczania do aplikacji komunikatu z Komunikacji w chmurze Firebase (FCM). Blokada uśpienia jest zwalniana po zakończeniu wykonywania metody onMessageReceived() komunikatu FCM.

Nazwy blokad uśpienia

Gdy urządzenie otrzyma wiadomość FCM, na krótko zostanie włączona blokada uśpienia o nazwie GOOGLE_C2DM. Na Androidzie 16 lub nowszym nazwa blokady uśpienia to GCM_MESSAGE.

Rekomendacja

Aby zoptymalizować działanie FCM, zalecamy stosowanie tych sprawdzonych metod:

  • Optymalizowanie częstotliwości dostarczania wiadomości FCM.
  • Nie używaj FCM o wysokim priorytecie, chyba że wiadomość rzeczywiście musi zostać dostarczona natychmiast.
  • Jak najszybciej wykonaj metodę onMessageReceived() lub zaplanuj kontynuowanie zadania przez instancję roboczą, jeśli wymagane jest dodatkowe przetwarzanie. Więcej informacji znajdziesz w wytycznych dotyczących Firebase.

JobScheduler

Zadania JobScheduler uzyskują blokady uśpienia podczas wykonywania zadań w tle. Blokady uśpienia są przypisywane do aplikacji, która utworzyła klasy worker.

Nazwy blokad uśpienia

Nazwy blokad uśpienia uzyskanych przez JobScheduler zależą od wersji systemu Android, na której są uruchamiane, oraz od celu zadania.

Elementy w nawiasach trójkątnych to zmienne. Na przykład „<package_name>” to nazwa pakietu aplikacji, a nie tekst <package name>. Jednak *job* to ciąg znaków *job* z gwiazdkami, które nie są używane jako symbole wieloznaczne.

Android 15 lub starszy

Zadania zainicjowane przez użytkownika tworzą blokady uśpienia o nazwach zgodnych z tym wzorcem:

*job*u/@<name_space>@/<package_name>/<classname>

Inne zadania używają tego wzorca:

*job*/@<name_space>@/<package_name>/<classname>
Android 16 QPR2 lub nowszy,

Zadania zainicjowane przez użytkownika tworzą blokady uśpienia o nazwach zgodnych z tym wzorcem:

*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Zadania priorytetowe używają tego wzorca:

*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Zwykłe zadania używają tego wzorca:

*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
Przykład

Załóżmy, że istnieje zadanie priorytetowe z przestrzenią nazw backup i tagiem śledzenia started. Nazwa pakietu to com.example.app, a klasa, która utworzyła zadanie, to com.backup.BackupFileService.

Na urządzeniach z Androidem 15 lub starszym blokada uśpienia będzie się nazywać:

*job*/@backup@/com.example.app/com.backup.BackupFileService

Na urządzeniach z Androidem 16 QPR2 lub nowszym blokada uśpienia będzie się nazywać:

*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService

Rekomendacja

  • Nie używaj ręcznej blokady uśpienia w przypadku pobierania lub przesyłania plików przez użytkownika. Zamiast tego użyj interfejsu API User-Initiated Data Transfer (UIDT). To jest wyznaczona ścieżka dla długotrwałych zadań przesyłania danych inicjowanych przez użytkownika.
  • Jeśli zidentyfikujesz blokady uśpienia utworzone przez JobScheduler z wysokim wykorzystaniem, może to być spowodowane nieprawidłową konfiguracją zadania, która uniemożliwia jego ukończenie w określonych sytuacjach. Rozważ przeanalizowanie przyczyn zatrzymania zadania, zwłaszcza jeśli często występuje STOP_REASON_TIMEOUT.
  • Sprawdź wykorzystanie zadań JobScheduler. W szczególności postępuj zgodnie z naszymi wskazówkami dotyczącymi optymalizacji wykorzystania baterii w przypadku interfejsów API do planowania zadań.

Lokalizacja

LocationManager i FusedLocationProviderClient używają blokad uśpienia, aby uzyskiwać i przekazywać lokalizację urządzenia. Blokady uśpienia są przypisywane do aplikacji, która wywołała te interfejsy API.

Nazwy blokad uśpienia

Usługi lokalizacyjne używają tych nazw:

  • CollectionLib-SigCollector
  • NetworkLocationLocator
  • NetworkLocationScanner
  • NlpCollectorWakeLock
  • NlpWakeLock
  • *location*

Rekomendacja

  • Zapoznaj się z naszymi wskazówkami dotyczącymi optymalizacji wykorzystania lokalizacji. Rozważ wdrożenie limitów czasu, wykorzystanie grupowania żądań lokalizacji lub pasywnych informacji o zmianie lokalizacji.
  • Unikaj uzyskiwania osobnej, ciągłej blokady uśpienia na potrzeby buforowania danych o lokalizacji, ponieważ jest to zbędne i powinno zostać usunięte. Gdy prosisz o informacje o zmianie lokalizacji za pomocą interfejsów API FusedLocationProvider lub LocationManager, system automatycznie wybudza urządzenie podczas wywołania zwrotnego zdarzenia lokalizacji. Zamiast tego przechowuj zdarzenia lokalizacji w pamięci lub pamięci masowej i okresowo przetwarzaj je za pomocą WorkManager.

Zdalne przesyłanie wiadomości

W tej sekcji omówiono scenariusze związane z wiadomościami zdalnymi, w których aplikacje mogą wymagać utrzymywania połączeń lub reagowania na zdarzenia z innych urządzeń, co może mieć wpływ na użycie blokady uśpienia. Częste przypadki użycia:

  • aplikacje towarzyszące do monitorowania obrazu lub dźwięku, które muszą monitorować zdarzenia występujące na urządzeniu zewnętrznym połączonym przez sieć lokalną;
  • aplikacje do obsługi wiadomości, które utrzymują połączenie z gniazdem sieciowym z wariantem na komputer;

Większość wybudzeń w tych scenariuszach zdalnego przesyłania wiadomości to blokady uśpienia jądra. Blokady uśpienia jądra nie są przypisywane do aplikacji, więc nie ma tu powiązanych nazw blokad uśpienia.

Rekomendacja

  • Jeśli zdarzenia sieciowe mogą być przetwarzane po stronie serwera, użyj FCM, aby otrzymywać informacje po stronie klienta. Jeśli wymagane jest dodatkowe przetwarzanie danych FCM, możesz zaplanować pracownika przyspieszonego.
  • Jeśli zdarzenia muszą być przetwarzane po stronie klienta za pomocą połączenia gniazda, blokada uśpienia nie jest potrzebna do nasłuchiwania przerw w zdarzeniach. Gdy pakiety danych docierają do Wi-Fi lub nadajnika w telefonie, sprzęt radiowy wyzwala przerwanie w postaci blokady uśpienia jądra. Następnie możesz zaplanować działanie instancji roboczej lub uzyskać blokadę uśpienia, aby przetworzyć dane.
  • Jeśli na przykład używasz ktor-network do nasłuchiwania pakietów danych w gnieździe sieciowym, blokadę uśpienia należy uzyskać tylko wtedy, gdy pakiety zostaną dostarczone do klienta.

WorkManager

Klasy worker biblioteki WorkManager uzyskują blokady uśpienia podczas wykonywania zadań w tle. Blokady uśpienia są przypisywane do aplikacji, która utworzyła klasy worker.

Nazwy blokad uśpienia

Nazwy blokad uśpienia uzyskanych przez bibliotekę WorkManager zależą od wersji systemu Android, na której działają.

Android 15 lub starszy

Zadania WorkManagera tworzą blokady uśpienia o nazwach zgodnych z tym wzorcem:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
Android 16 QPR2 lub nowszy,

Zadania priorytetowe tworzą blokady uśpienia o nazwach zgodnych z tym wzorcem:

*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

Zwykłe zadania mają ten wzorzec:

*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

Domyślnie nazwa workera to <trace_tag>.

Przykład

Załóżmy, że istnieje priorytetowy worker o nazwie BackupFileWorker. Nazwa pakietu to com.example.app.

Na urządzeniach z Androidem 15 lub starszym blokada uśpienia będzie się nazywać:

*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

Na urządzeniach z Androidem 16 QPR2 lub nowszym, które korzystają z WorkManager 2.10.0+, blokada uśpienia będzie się nazywać:

*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

Rekomendacja

  • Uaktualnij wersję WorkManagera do najnowszej wersji stabilnej, aby tagi blokady uśpienia były bardziej szczegółowe na Androidzie 16 QPR2 lub nowszym.
  • Sprawdź wykorzystanie workerów WorkManagera. W szczególności sprawdź, czy jest ona zgodna z naszymi wskazówkami dotyczącymi optymalizacji wykorzystania baterii w przypadku interfejsów API do planowania zadań. Aby tagi blokady uśpienia były bardziej szczegółowe na Androidzie 16 QPR2 lub nowszym, użyj metody setTraceTag na instancji roboczej, aby dodać więcej informacji na potrzeby debugowania, np. o klasie, która zaplanowała instancję roboczą.
  • Jeśli zidentyfikujesz blokady uśpienia utworzone przez WorkManagera, które są często używane, może to oznaczać, że worker został nieprawidłowo skonfigurowany i nie kończy działania w niektórych scenariuszach. Rozważ przeanalizowanie przyczyn zatrzymania instancji roboczych, zwłaszcza jeśli często występuje błąd STOP_REASON_TIMEOUT.
  • Oprócz rejestrowania przyczyn zatrzymania instancji roboczych zapoznaj się z naszą dokumentacją dotyczącą debugowania instancji roboczych. Możesz też zbierać i analizować śledzenie systemu, aby dowiedzieć się, kiedy blokady uśpienia są uzyskiwane i zwalniane.

_UNKNOWN

Jeśli narzędzia do debugowania uznają, że nazwa blokady uśpienia zawiera informacje umożliwiające identyfikację, nie wyświetlają jej. Zamiast tego oznaczają blokadę uśpienia jako _UNKNOWN. Narzędzia mogą to robić na przykład, jeśli nazwa blokady uśpienia zawiera adres e-mail.

Rekomendacja

Stosuj sprawdzone metody nazewnictwa blokad uśpienia i unikaj używania w nazwach blokad informacji umożliwiających identyfikację. Jeśli znajdziesz blokadę uśpienia o nazwie _UNKNOWN przypisaną do Twojej aplikacji, spróbuj ustalić, która to blokada, i nadaj jej inną nazwę.