Wiadomości o usługach

Optymalizowanie baterii aplikacji za pomocą wskaźnika blokady uśpienia w Android Vitals

Czas czytania: 7 minut
Alice Yuan
Inżynier ds. relacji z deweloperami

Czas pracy baterii jest kluczowym aspektem wrażeń użytkownika, a blokady wybudzania odgrywają w tym przypadku ważną rolę. Czy używasz ich w nadmiarze? W tym poście na blogu wyjaśnimy, czym są blokady wybudzania, jakie są sprawdzone metody ich używania i jak lepiej zrozumieć zachowanie własnej aplikacji dzięki danym z Konsoli Play.

Nadmierne używanie częściowych blokad wybudzenia w Android Vitals

Konsola Play monitoruje teraz szybkie zużycie baterii, a kluczowym wskaźnikiem wydajności jest nadmierne użycie częściowych blokad uśpienia.

Ta funkcja zwiększa znaczenie efektywności baterii obok dotychczasowych wskaźników stabilności: nadmiernej liczby awarii i błędów ANR widocznych dla użytkowników. Określiliśmy próg niewłaściwego działania dotyczący nadmiernych blokad uśpienia. Jeśli od 1 marca 2026 r. Twój tytuł nie będzie spełniać tego progu jakości, możemy wykluczyć go z najważniejszych miejsc, w których użytkownicy mogą odkrywać treści, np. z rekomendacji. W niektórych przypadkach w informacjach o aplikacji możemy wyświetlać ostrzeżenie, aby poinformować użytkowników, że aplikacja może powodować szybkie zużycie baterii.

warning.png

Ostrzeżenie o nadmiernej liczbie blokad uśpienia w podsumowaniu Android Vitals.

W przypadku urządzeń mobilnych wskaźnik Android Vitals dotyczy blokad uśpienia, które nie są zwolnione z tego obowiązku i są uzyskiwane, gdy ekran jest wyłączony, a aplikacja działa w tle lub jako usługa (działająca) na pierwszym planie. Android Vitals uznaje użycie częściowych blokad uśpienia za nadmierne, jeśli:

  • Blokady uśpienia są utrzymywane przez co najmniej 2 godziny w ciągu 24 godzin.
  • Wpływa na ponad 5% sesji w aplikacji (średnia z 28 dni).

Blokady uśpienia utworzone przez interfejsy API zainicjowane przez użytkownika w przypadku dźwięku, lokalizacjiharmonogramu zadań są wyłączone z obliczeń blokad uśpienia.

Informacje o blokadach uśpienia

Blokada uśpienia to mechanizm, który pozwala aplikacji utrzymać działanie procesora urządzenia nawet wtedy, gdy użytkownik nie korzysta z niego aktywnie. 

Częściowa blokada uśpienia utrzymuje działanie procesora nawet wtedy, gdy ekran jest wyłączony, co zapobiega przejściu procesora w stan „zawieszenia” o niskim poborze mocy. Pełna blokada uśpienia utrzymuje włączony ekran i procesor.

Częściowe blokady uśpienia można uzyskać na 2 sposoby:

  • Aplikacja ręcznie uzyskuje i zwalnia blokadę uśpienia za pomocą interfejsów API PowerManager w określonym przypadku użycia. Często blokada ta jest uzyskiwana w połączeniu z usługą (działającą) na pierwszym planie – interfejsem API cyklu życia platformy przeznaczonym do operacji widocznych dla użytkownika.
  • Blokada uśpienia może też być uzyskiwana przez inny interfejs API i przypisywana do aplikacji ze względu na korzystanie z tego interfejsu. Więcej informacji znajdziesz w sekcji dotyczącej sprawdzonych metod.

Blokady wybudzania są niezbędne w przypadku zadań takich jak pobieranie dużego pliku zainicjowane przez użytkownika, ale ich nadmierne lub nieprawidłowe użycie może prowadzić do szybkiego zużycia baterii. Zdarza się, że aplikacje utrzymują blokady wybudzania przez wiele godzin lub nie zwalniają ich prawidłowo, co powoduje skargi użytkowników na szybkie zużycie baterii, nawet gdy nie korzystają z aplikacji.

Sprawdzone metody korzystania z blokad uśpienia

Zanim omówimy, jak debugować nadmierne użycie blokady uśpienia, upewnij się, że stosujesz sprawdzone metody dotyczące blokad uśpienia. 

Zastanów się nad tymi 4 kluczowymi pytaniami.


1. Czy rozważasz inne opcje blokady uśpienia?

Zanim rozważysz ręczne uzyskanie częściowej blokady uśpienia, postępuj zgodnie z tym schematem blokowym:

wakelock.png

Schemat blokowy określający, kiedy ręcznie uzyskać blokadę wybudzenia

  1. Czy ekran musi być włączony?
  2. Czy aplikacja uruchamia usługę na pierwszym planie?
    • Nie: nie musisz ręcznie uzyskiwać blokady wybudzenia.
  3. Czy zawieszenie urządzenia ma negatywny wpływ na wrażenia użytkownika?
    • Nie: na przykład aktualizacja powiadomienia po wybudzeniu urządzenia nie wymaga blokady uśpienia.
    • Tak: jeśli zapobieganie zawieszeniu urządzenia jest kluczowe, np. w przypadku ciągłej komunikacji z urządzeniem zewnętrznym, kontynuuj.
  4. Czy jest już interfejs API, który utrzymuje urządzenie w stanie aktywności w Twoim imieniu?
  5. Jeśli udało Ci się odpowiedzieć na wszystkie te pytania i nie ma alternatywnego rozwiązania, możesz ręcznie uzyskać blokadę uśpienia.

2. Czy prawidłowo nazywasz blokadę uśpienia?

Podczas ręcznego uzyskiwania blokad uśpienia ważne jest prawidłowe nazewnictwo, które ułatwia debugowanie:

  • Nie podawaj w nazwie żadnych informacji umożliwiających identyfikację, takich jak adresy e-mail. Jeśli zostaną wykryte informacje umożliwiające identyfikację, blokada uśpienia zostanie zarejestrowana jako _UNKNOWN, co utrudni debugowanie.
  • Nie nadawaj blokadzie uśpienia nazwy automatycznie przy użyciu nazw klas lub metod, ponieważ mogą one zostać zaciemnione przez narzędzia takie jak Proguard. Zamiast tego użyj ciągu znaków zakodowanego na stałe.
  • Nie dodawaj liczników ani unikalnych identyfikatorów do tagów blokady uśpienia. Ten sam tag powinien być używany za każdym razem, gdy blokada uśpienia jest aktywna, aby system mógł agregować dane o użytkowaniu według nazwy, co ułatwia wykrywanie nietypowych zachowań.

3. Czy uzyskana blokada uśpienia jest zawsze zwalniana?

Jeśli blokadę uśpienia uzyskujesz ręcznie, upewnij się, że zawsze jest ona zwalniana. Niezwolnienie blokady uśpienia może spowodować szybkie zużycie baterii. 

Jeśli na przykład podczas wykonywania funkcji processingWork() zostanie zgłoszony nieobsłużony wyjątek, wywołanie funkcji release() może nigdy nie nastąpić. Zamiast tego możesz użyć bloku try-finally, aby zagwarantować zwolnienie blokady uśpienia, nawet jeśli wystąpi wyjątek.

Możesz też dodać limit czasu do blokady uśpienia, aby mieć pewność, że zostanie ona zwolniona po określonym czasie, co zapobiegnie jej nieograniczonemu utrzymywaniu.

fun processingWork() {
    wakeLock.apply {
        try {
            acquire(60 * 10 * 1000) // timeout after 10 minutes
            doTheWork()
        } finally {
            release()
        }
    }
}

4. Czy można zmniejszyć częstotliwość wybudzania?

W przypadku okresowych żądań danych kluczowe dla optymalizacji baterii jest ograniczenie częstotliwości wybudzania urządzenia przez aplikację. Oto kilka przykładów zmniejszenia częstotliwości wybudzania:

  • WorkManager: zwiększ interwał okresowy w PeriodicWorkRequest.
  • SensorManager: korzystaj z grupowania, określając parametr maxReportLatencyMs podczas rejestrowania detektora zdarzeń.
  • Dostawca uśrednionej lokalizacji:
    • Zmniejsz częstotliwość pobierania lokalizacji, używając funkcji getLastLocation do pobierania ostatniej lokalizacji z pamięci podręcznej.
    • Użyj metody setPriority(PRIORITY_PASSIVE), aby zmniejszyć zużycie baterii.
    • Możesz też skorzystać z mechanizmu grupowania lokalizacji, ustawiając minimalny interwał aktualizacji za pomocą metody setMinUpdateIntervalMillis.

Więcej informacji znajdziesz w dokumentacji dotyczącej sprawdzonych metod korzystania z blokady wybudzania.

Debugowanie nadmiernego użycia blokad uśpienia

Nawet przy najlepszych intencjach może dojść do nadmiernego użycia blokady uśpienia. Jeśli Twoja aplikacja zostanie oznaczona w Konsoli Play, możesz ją debugować w ten sposób:

Wstępna identyfikacja w Konsoli Play

Panel Nadmierne częściowe blokady uśpienia w Androidzie zawiera podział nazw blokad uśpienia, które nie są zwolnione z tego obowiązku, powiązanych z aplikacją, a także informacje o sesjach, których to dotyczy, i czasie trwania. Przypomnienie o korzystaniu z dokumentacji, która pomoże Ci ustalić, czy nazwa blokady uśpienia jest utrzymywana przez aplikację, czy przez inny interfejs API.

breakdowns2.png

W panelu Zbyt wiele częściowych blokad uśpienia w Android Vitals przewinięto w dół do sekcji podziałów, aby wyświetlić tagi zbyt wielu blokad uśpienia.

Debugowanie nadmiernej liczby blokad uśpienia utrzymywanych przez klasy worker lub zadania

Blokady uśpienia utrzymywane przez proces roboczy można rozpoznać po tej nazwie:

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

Pełna lista wariantów nazw blokad uśpienia utrzymywanych przez worker jest dostępna w dokumentacji. Aby debugować te blokady wybudzania, możesz użyć narzędzia Background Task Inspector do debugowania lokalnego lub funkcji getStopReason do debugowania problemów w terenie. 

Inspektor zadań w tle w Android Studio

taskinspector.png


Zrzut ekranu Background Task Inspector, który wykrył proces roboczy „WeatherSyncWorker”, który często ponawiał próby i ponosił porażkę.

Do lokalnego debugowania problemów z WorkManager używaj tego narzędzia na emulatorze lub podłączonym urządzeniu (API na poziomie 26 lub wyższym). Wyświetla ono listę procesów i ich stanów (zakończony, wykonywany, w kolejce), co pozwala sprawdzać szczegóły i rozumieć łańcuchy procesów. 

Na przykład może pokazywać, czy pracownik często nie wykonuje zadania lub ponawia próbę z powodu ograniczeń systemu. 

Więcej informacji znajdziesz w dokumentacji Inspektora zadań w tle.

WorkManager getStopReason

Do debugowania w terenie procesów roboczych z nadmierną liczbą blokad wybudzania używaj WorkInfo.getStopReason() w przypadku WorkManagera w wersji 2.9.0 lub nowszej albo JobParameters.getStopReason() w przypadku JobSchedulera w wersji SDK 31 lub nowszej. 

Ten interfejs API pomaga rejestrować przyczynę zatrzymania pracownika (np. STOP_REASON_TIMEOUT, STOP_REASON_QUOTA), wskazując problemy, takie jak częste przekroczenia limitu czasu z powodu wyczerpania czasu działania.

backgroundScope.launch {
    WorkManager.getInstance(context)
        .getWorkInfoByIdFlow(workRequest.id)
        .collect { workInfo ->
            logStopReason(workRequest.id, workInfo?.stopReason)
        }
}

Więcej informacji znajdziesz w artykule Optymalizacja wykorzystania baterii w przypadku interfejsów API do planowania zadań.

Debugowanie innych typów nadmiernych blokad uśpienia

W bardziej złożonych scenariuszach, w których blokady uśpienia są utrzymywane ręcznie lub przez interfejsy API, zalecamy debugowanie za pomocą zbierania śladów systemu.

Zbieranie śladów systemowych

Ślad systemowy  to zaawansowane narzędzie do debugowania, które rejestruje szczegółowe informacje o aktywności systemu w określonym czasie. Zawiera dane o stanie procesora, aktywności wątków, aktywności sieciowej i dane związane z baterią, takie jak czas trwania zadania i użycie blokady wybudzania.

Ślad systemowy możesz zarejestrować na kilka sposobów: 

powermgmt.png

Włącz kategorię Atrace „power:PowerManagement” w interfejsie Perfetto na karcie Aplikacje i usługi na Androida. 

Niezależnie od wybranej metody ważne jest, aby zbierać kategorię Atrace „power:PowerManagement”, co umożliwi wyświetlanie ścieżek stanu urządzenia. 

Sprawdzanie interfejsu Perfetto i analiza SQL

Ślady systemowe można otwierać i sprawdzać w Perfetto UI. Po otwarciu śladu zobaczysz wizualizację różnych procesów na osi czasu. W tym przewodniku skupimy się na ścieżkach w sekcji „Stan urządzenia”.

perfetto.png


Przypnij ścieżki w sekcji „Stan urządzenia”, takie jak „Najpopularniejsza aplikacja”, „Stan ekranu”, „Długie blokady uśpienia” i „Zadania”, aby wizualnie identyfikować długotrwałe fragmenty blokady uśpienia.

Każdy blok zawiera nazwę wydarzenia, datę jego rozpoczęcia i zakończenia. W Perfetto nazywa się to wycinkiem.

Do analizy wielu śladów na dużą skalę możesz użyć analizy SQL w Perfetto. Zapytanie SQL może znaleźć wszystkie blokady wybudzania posortowane według czasu trwania, co pomaga zidentyfikować główne przyczyny nadmiernego zużycia.

Oto przykładowe zapytanie sumujące wszystkie tagi blokady uśpienia, które wystąpiły w śledzeniu systemu, uporządkowane według łącznego czasu trwania:

SELECT slice.name as name, track.name as track_name,SUM(dur / 100000) as total_dur_ms
FROM slice
JOIN track ON slice.track_id = track.id
WHERE track.name = 'WakeLocks'GROUP BY slice.name, track.name
ORDER BY total_dur_ms DESC

Korzystanie z narzędzia ProfilingManager do zbierania śladów w terenie

W przypadku problemów, które trudno odtworzyć, interfejs ProfilingManager (dodany w pakiecie SDK 35) to programowy interfejs API, który umożliwia deweloperom zbieranie śladów systemowych w terenie za pomocą wyzwalaczy początkowych i końcowych. Zapewnia większą kontrolę nad punktami początkowymi i końcowymi wyzwalającymi zbieranie profili oraz wymusza ograniczanie liczby żądań na poziomie systemu, aby zapobiec negatywnemu wpływowi na wydajność urządzenia. 

Więcej informacji o wdrażaniu zbierania śladów systemu w terenie, w tym o tym, jak programowo rejestrować ślady, analizować dane profilowania i korzystać z lokalnych poleceń debugowania, znajdziesz w dokumentacji ProfilingManager.

Ślady systemowe zebrane za pomocą ProfilingManager będą wyglądać podobnie do tych zebranych ręcznie, ale procesy systemowe i inne procesy aplikacji zostaną z nich usunięte.

Podsumowanie

Wskaźnik zbyt wielu częściowych blokad uśpienia w Android Vitals to tylko niewielka część naszych działań, które mają na celu pomóc deweloperom w ograniczaniu szybkiego zużycia baterii i poprawianiu jakości aplikacji. 

Dzięki zrozumieniu i prawidłowemu wdrożeniu blokad uśpienia możesz znacznie zoptymalizować wykorzystanie baterii przez aplikację. Korzystanie z alternatywnych interfejsów API, przestrzeganie sprawdzonych metod dotyczących blokad uśpienia oraz używanie zaawansowanych narzędzi do debugowania, takich jak Background Task Inspector, śledzenie systemu i ProfilingManager, to klucz do sukcesu aplikacji w Google Play.

Autor:

Czytaj dalej