Egzekwowanie wymagań dotyczących jakości technicznej w zakresie baterii: jak zoptymalizować typowe przypadki użycia blokady uśpienia
Czas czytania: 8 min
W związku z tym, że nadmierne zużycie baterii jest dla użytkowników Androida bardzo ważne, Google podejmuje znaczące kroki, aby pomóc deweloperom w tworzeniu bardziej energooszczędnych aplikacji. 1 marca 2026 r. Sklep Google Play zaczął wdrażać zmiany w zakresie jakości technicznej blokad uśpienia, aby zmniejszyć szybkie zużycie baterii. W ciągu najbliższych tygodni te zmiany będą stopniowo wprowadzane w aplikacjach, których dotyczą. Aplikacje, które stale przekraczają próg „Nadmierne częściowe blokady uśpienia” w Android Vitals, mogą odczuć wymierne skutki w Sklepie, w tym ostrzeżenia na stronie aplikacji i wykluczenie z powierzchni, na których można odkrywać aplikacje, takich jak rekomendacje.
Jeśli Twoja aplikacja przekracza próg niewłaściwego działania, użytkownicy mogą zobaczyć ostrzeżenie na jej stronie w Sklepie.
Dzięki tej inicjatywie wydajność baterii stała się podstawowym wskaźnikiem obok wskaźników stabilności, takich jak awarie i błędy ANR. „Próg niewłaściwego działania” jest definiowany jako utrzymywanie częściowej blokady uśpienia, która nie jest wyłączona z tego progu, przez co najmniej 2 godziny średnio przy wyłączonym ekranie w ponad 5% sesji użytkowników w ciągu ostatnich 28 dni. Blokada uśpienia jest wyłączona z tego progu, jeśli jest to blokada uśpienia utrzymywana przez system, która zapewnia wyraźne korzyści dla użytkownika, których nie można dalej optymalizować, np. odtwarzanie dźwięku, dostęp do lokalizacji lub przesyłanie danych inicjowane przez użytkownika. Pełną definicję nadmiernych blokad uśpienia znajdziesz w dokumentacji Android Vitals.
W ramach naszej ciągłej inicjatywy mającej na celu poprawę żywotności baterii w ekosystemie Androida przeanalizowaliśmy tysiące aplikacji i sposób, w jaki korzystają one z częściowych blokad uśpienia. Chociaż blokady uśpienia są czasami konieczne, często widzimy, że aplikacje utrzymują je nieefektywnie lub niepotrzebnie, mimo że istnieją bardziej wydajne rozwiązania. W tym poście na blogu omówimy najczęstsze scenariusze, w których występują nadmierne blokady uśpienia, oraz nasze rekomendacje dotyczące ich optymalizacji.Widzimy już wymierne sukcesy partnerów, takich jak WHOOP, którzy wykorzystali te rekomendacje do optymalizacji działania w tle.
Korzystanie z usługi na pierwszym planie a częściowe blokady uśpienia
Często widzimy, że deweloperzy mają trudności ze zrozumieniem różnicy między 2 koncepcjami dotyczącymi wykonywania w tle: usługą na pierwszym planie a częściowymi blokadami uśpienia.
Usługa na pierwszym planie to interfejs API cyklu życia, który sygnalizuje systemowi, że aplikacja wykonuje pracę widoczną dla użytkownika i nie powinna zostać zamknięta w celu odzyskania pamięci. Nie zapobiega jednak automatycznie przechodzeniu procesora w stan uśpienia, gdy ekran jest wyłączony. Z kolei częściowa blokada uśpienia to mechanizm zaprojektowany specjalnie po to, aby procesor działał nawet wtedy, gdy ekran jest wyłączony.
Chociaż usługa na pierwszym planie jest często niezbędna do kontynuowania działania użytkownika, ręczne uzyskanie częściowej blokady uśpienia jest konieczne tylko w połączeniu z usługą na pierwszym planie na czas działania procesora. Ponadto nie musisz używać blokady uśpienia, jeśli korzystasz już z interfejsu API, który zapobiega przechodzeniu urządzenia w stan uśpienia.
Aby mieć pewność, że dobrze rozumiesz, jakiego narzędzia użyć, aby uniknąć uzyskania blokady uśpienia w sytuacjach, w których nie jest to konieczne, zapoznaj się ze schematem blokowym w artykule Wybór odpowiedniego interfejsu API, który zapobiega przechodzeniu urządzenia w stan uśpienia.
Biblioteki innych firm uzyskujące blokady uśpienia
Często zdarza się, że aplikacja otrzymuje flagę wskazującą na nadmierne blokady uśpienia utrzymywane przez pakiet SDK innej firmy lub interfejs API systemu działający w jej imieniu. Aby zidentyfikować i rozwiązać te problemy, zalecamy wykonanie tych czynności:
- Sprawdź Android Vitals: znajdź dokładną nazwę problematycznej blokady uśpienia na panelu Nadmierne częściowe blokady uśpienia. Porównaj tę nazwę ze wskazówkami w artykule Identyfikowanie blokad uśpienia utworzonych przez inne interfejsy API, aby sprawdzić, czy została utworzona przez znany interfejs API systemu lub bibliotekę Jetpack. Jeśli tak, być może trzeba będzie zoptymalizować sposób korzystania z interfejsu API i zapoznać się z zalecanymi wskazówkami.
- Zarejestruj ślad systemu: jeśli nie można łatwo zidentyfikować blokady uśpienia, odtwórz problem lokalnie za pomocą śladu systemu i sprawdź go w interfejsie Perfetto. Więcej informacji o tym, jak to zrobić, znajdziesz w sekcji Debugowanie innych typów nadmiernych blokad uśpienia w tym poście na blogu.
- Oceń alternatywy: jeśli problem powoduje nieefektywna biblioteka innej firmy, której nie można skonfigurować tak, aby uwzględniała żywotność baterii, rozważ zgłoszenie problemu właścicielom pakietu SDK, znalezienie alternatywnego pakietu SDK lub samodzielne utworzenie tej funkcji.
Typowe scenariusze blokad uśpienia
Poniżej znajdziesz zestawienie niektórych konkretnych przypadków użycia, które przeanalizowaliśmy, oraz zalecane sposoby optymalizacji implementacji blokady uśpienia.
Przesyłanie lub pobieranie inicjowane przez użytkownika
Przykłady zastosowania:
- Aplikacje do strumieniowego przesyłania wideo, w których użytkownik inicjuje pobieranie dużego pliku w celu uzyskania dostępu offline.
- Aplikacje do tworzenia kopii zapasowych multimediów, w których użytkownik inicjuje przesyłanie swoich najnowszych zdjęć za pomocą powiadomienia.
Jak zmniejszyć liczbę blokad uśpienia:
- Nie uzyskuj ręcznej blokady uśpienia. Zamiast tego użyj interfejsu User-Initiated Data Transfer (UIDT) API. Jest to wyznaczona ścieżka dla długotrwałych zadań przesyłania danych inicjowanych przez użytkownika, która jest wyłączona z obliczeń nadmiernych blokad uśpienia.
Jednorazowe lub okresowe synchronizacje w tle
Przykłady zastosowania:
- Aplikacja wykonuje okresowe synchronizacje w tle, aby pobierać dane na potrzeby dostępu offline.
- Aplikacje krokomierza, które okresowo pobierają liczbę kroków.
Jak zmniejszyć liczbę blokad uśpienia:
- Nie uzyskuj ręcznej blokady uśpienia. Użyj biblioteki WorkManager skonfigurowanej do pracy jednorazowej lub okresowej. Biblioteka
WorkManageruwzględnia kondycję systemu, grupując zadania i stosując minimalny interwał okresowy (15 minut), który jest zwykle wystarczający do aktualizacji w tle. - Jeśli zidentyfikujesz blokady uśpienia utworzone przez bibliotekę
WorkManagerlub JobScheduler z wysokim wykorzystaniem blokad uśpienia, może to być spowodowane tym, że pracownik został nieprawidłowo skonfigurowany i nie może ukończyć pracy w niektórych scenariuszach. Rozważ przeanalizowanie przyczyn zatrzymania pracownika, zwłaszcza jeśli często występuje przyczyna STOP_REASON_TIMEOUT.
workManager.getWorkInfoByIdFlow(syncWorker.id)
.collect { workInfo ->
if (workInfo != null) {
val stopReason = workInfo.stopReason
logStopReason(syncWorker.id, stopReason)
}
}- Oprócz rejestrowania przyczyn zatrzymania pracownika zapoznaj się z dokumentacją dotyczącą debugowania pracowników. Rozważ też zbieranie i analizowanie śladów systemu , aby dowiedzieć się, kiedy blokady uśpienia są uzyskiwane i zwalniane.
- Na koniec zapoznaj się z naszym studium przypadku dotyczącym firmy WHOOP, która zdołała wykryć problem z konfiguracją swoich pracowników i znacznie zmniejszyć wpływ blokad uśpienia.
Komunikacja Bluetooth
Przykłady zastosowania:
- Aplikacja urządzenia towarzyszącego prosi użytkownika o sparowanie zewnętrznego urządzenia Bluetooth.
- Aplikacja urządzenia towarzyszącego nasłuchuje zdarzeń sprzętowych na urządzeniu zewnętrznym i zmian widocznych dla użytkownika w powiadomieniu.
- Użytkownik aplikacji urządzenia towarzyszącego inicjuje przesyłanie plików między urządzeniem mobilnym a urządzeniem Bluetooth.
- Aplikacja urządzenia towarzyszącego okresowo aktualizuje oprogramowanie układowe urządzenia zewnętrznego przez Bluetooth.
Jak zmniejszyć liczbę blokad uśpienia:
- Użyj parowania urządzenia towarzyszącego, aby sparować urządzenia Bluetooth i uniknąć ręcznego blokowania uśpienia podczas parowania Bluetooth.
- Zapoznaj się ze wskazówkami w artykule Komunikacja w tle , aby dowiedzieć się, jak prowadzić komunikację Bluetooth w tle.
- Jeśli opóźnienie komunikacji nie ma wpływu na użytkownika, często wystarczy użyć biblioteki
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.
Lokalizowanie
Przykłady zastosowania:
- Aplikacje fitness, które zapisują w pamięci podręcznej dane o lokalizacji w celu późniejszego przesłania, np. do wyznaczania tras biegu.
- Aplikacje do dostarczania jedzenia, które pobierają dane o lokalizacji z dużą częstotliwością, aby aktualizować postęp dostawy w powiadomieniu lub widżecie.
Jak zmniejszyć liczbę blokad uśpienia:
- Zapoznaj się z naszymi wskazówkami dotyczącymi optymalizacji korzystania z lokalizacji. Aby zapewnić wydajność baterii, rozważ wdrożenie limitów czasu, grupowanie żądań lokalizacji lub korzystanie z pasywnych aktualizacji lokalizacji.
- Gdy żądasz aktualizacji lokalizacji za pomocą interfejsów FusedLocationProvider API lub LocationManager API, system automatycznie wybudza urządzenie podczas wywołania zwrotnego zdarzenia lokalizacji. Ta krótka blokada uśpienia zarządzana przez system jest wyłączona z obliczeń nadmiernych częściowych blokad uśpienia.
- Unikaj uzyskiwania oddzielnej, ciągłej blokady uśpienia na potrzeby zapisywania w pamięci podręcznej danych o lokalizacji, ponieważ jest to zbędne. Zamiast tego zapisuj zdarzenia lokalizacji w pamięci lub pamięci lokalnej i używaj biblioteki WorkManager do ich przetwarzania w regularnych odstępach czasu.
override fun onCreate(savedInstanceState: Bundle?) {
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
// System wakes up CPU for short duration
for (location in locationResult.locations){
// Store data in memory to process at another time
}
}
}
}Monitorowanie czujników z dużą częstotliwością
Przykłady zastosowania:
- Aplikacje krokomierza, które pasywnie zbierają dane o krokach lub przebytej odległości.
- Aplikacje zabezpieczające, które monitorują czujniki urządzenia pod kątem szybkich zmian w czasie rzeczywistym, aby udostępniać funkcje takie jak wykrywanie wypadków lub upadków.
Jak zmniejszyć liczbę blokad uśpienia:
- Jeśli używasz SensorManager, ogranicz jego użycie do okresowych interwałów i tylko wtedy, gdy użytkownik wyraźnie przyzna dostęp za pomocą interakcji z interfejsem. Monitorowanie czujników z dużą częstotliwością może znacznie wyczerpać baterię ze względu na liczbę wybudzeń procesora i przetwarzania.
- Jeśli śledzisz liczbę kroków lub przebytą odległość, zamiast używać SensorManager, użyj Recording API lub rozważ użycie Health Connect, aby uzyskać dostęp do danych historycznych i zagregowanych danych o krokach na urządzeniu i rejestrować dane w sposób oszczędzający baterię.
- Jeśli rejestrujesz czujnik za pomocą SensorManager, określ wartość maxReportLatencyUs wynoszącą co najmniej 30 sekund, aby używać grupowania danych z czujników i zminimalizować częstotliwość przerwań procesora. Gdy urządzenie zostanie później wybudzone przez inny wyzwalacz, np. interakcję użytkownika, pobieranie lokalizacji lub zaplanowane zadanie, system natychmiast wyśle dane z czujników zapisane w pamięci podręcznej.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(this,
accelerometer,
samplingPeriodUs, // How often to sample data
maxReportLatencyUs // Key for sensor batching
)- Jeśli Twoja aplikacja wymaga danych o lokalizacji i danych z czujników, zsynchronizuj ich pobieranie i przetwarzanie. Dzięki wykorzystaniu odczytów z czujników w ramach krótkiej blokady uśpienia, którą system utrzymuje na potrzeby aktualizacji lokalizacji, nie musisz używać blokady uśpienia, aby utrzymać procesor w stanie aktywności. Do obsługi przesyłania i przetwarzania tych połączonych danych użyj pracownika lub krótkotrwałej blokady uśpienia.
Zdalne przesyłanie wiadomości
Przykłady zastosowania:
- Aplikacje towarzyszące do monitorowania wideo lub dźwięku, które muszą monitorować zdarzenia występujące na urządzeniu zewnętrznym połączonym za pomocą sieci lokalnej.
- Aplikacje do obsługi wiadomości, które utrzymują połączenie gniazda sieciowego z wersją na komputery.
Jak zmniejszyć liczbę blokad uśpienia:
- Jeśli zdarzenia sieciowe można przetwarzać po stronie serwera, użyj FCM aby otrzymywać informacje na kliencie. Jeśli wymagane jest dodatkowe przetwarzanie danych FCM, możesz zaplanować przyspieszonego pracownika.
- Jeśli zdarzenia muszą być przetwarzane po stronie klienta za pomocą połączenia gniazda, nie jest potrzebna blokada uśpienia, aby nasłuchiwać przerwań zdarzeń. Gdy pakiety danych docierają do radia Wi-Fi lub komórkowego, sprzęt radiowy wywołuje przerwanie sprzętowe w postaci blokady uśpienia jądra. Możesz wtedy zaplanować pracownika lub uzyskać blokadę uśpienia, aby przetworzyć dane.
- Jeśli na przykład używasz biblioteki ktor-network do nasłuchiwania pakietów danych w gnieździe sieciowym, blokadę uśpienia należy uzyskać tylko wtedy, gdy pakiety zostały dostarczone do klienta i wymagają przetworzenia.
val readChannel = socket.openReadChannel()
while (!readChannel.isClosedForRead) {
// CPU can safely sleep here while waiting for the next packet
val packet = readChannel.readRemaining(1024)
if (!packet.isEmpty) {
// Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent)
performWorkWithWakeLock {
val data = packet.readBytes()
// Additional logic to process data packets
}
}
}Podsumowanie
Dzięki przyjęciu tych zalecanych rozwiązań w typowych przypadkach użycia, takich jak synchronizacje w tle, lokalizowanie, monitorowanie czujników i komunikacja sieciowa, deweloperzy mogą zmniejszyć niepotrzebne użycie blokad uśpienia. Aby dowiedzieć się więcej, przeczytaj nasz inny post na blogu lub obejrzyj film techniczny o tym, jak wykrywać i debugować blokady uśpienia: Optymalizacja baterii aplikacji za pomocą wskaźnika blokady uśpienia w Android Vitals. Zapoznaj się też z naszą zaktualizowaną dokumentacją dotyczącą blokad uśpienia. Aby pomóc nam w dalszym ulepszaniu zasobów technicznych, podziel się dodatkowymi opiniami na temat naszych wskazówek w ankiecie dotyczącej dokumentacji.
-
PoradnikiChociaż wydajność aplikacji jest często utożsamiana z płynnym interfejsem i krótkim czasem uruchamiania, pamięć jest cichym fundamentem, na którym opierają się te widoczne wskaźniki. Nie jest tajemnicą, że obserwujemy zmianę, w której pamięć urządzenia jest ważniejsza niż kiedykolwiek.
Alice Yuan, Ajesh Pai, Fung Lam • Czas czytania: 10 min -
PoradnikiPrzewodnik po osiąganiu kolejnych poziomów wydajności zawiera 5 poziomów. Zaczniemy od poziomu 1, który wprowadza narzędzia do optymalizacji wydajności wymagające minimalnego wysiłku wdrożeniowego, i przejdziemy do poziomu 5, idealnego dla aplikacji, które mają zasoby do utrzymywania niestandardowego frameworka wydajności.
Alice Yuan • Czas czytania: 9 min -
r.r.
PoradnikiZ przyjemnością informujemy, że udostępniamy nowy zweryfikowany adres e-mail wydany przez Google, który deweloperzy mogą teraz pobierać bezpośrednio z interfejsu Digital Credential API Menedżera danych logowania na Androidzie.
Niharika Arora, Jean-Pierre Pralle • Czas czytania: 3 min
Otrzymuj co tydzień najnowsze informacje o tworzeniu aplikacji na Androida na swoją skrzynkę odbiorczą.