Instrukcje

Wymagania dotyczące jakości technicznej baterii: jak optymalizować typowe przypadki użycia blokady wybudzania

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

Zdając sobie sprawę, że szybkie zużycie baterii jest dla użytkowników Androida natychmiastowym skojarzeniem, Google podejmuje znaczące kroki, aby pomóc deweloperom w tworzeniu aplikacji bardziej energooszczędnych. 1 marca 2026 r. w Sklepie Google Play zaczęliśmy wdrażać rozwiązania techniczne dotyczące jakości blokady uśpienia, aby zmniejszyć szybkie zużycie baterii. W ciągu najbliższych tygodni będziemy stopniowo wprowadzać tę zmianę w aplikacjach, których dotyczy ten problem. Aplikacje, które stale przekraczają próg „Nadmierne częściowe blokowanie wybudzania” w Android Vitals, mogą odczuć negatywne skutki w zakresie obecności w sklepie, w tym ostrzeżenia na stronie aplikacji i wykluczenie z platform, na których użytkownicy mogą odkrywać aplikacje, np. z rekomendacji.

appDetails.png

Jeśli aplikacja przekroczy próg niewłaściwego działania, na jej stronie w Sklepie może pojawić się ostrzeżenie. 

Dzięki tej inicjatywie wydajność baterii stała się jednym z podstawowych wskaźników, obok wskaźników stabilności, takich jak awarie i błędy ANR. „Próg niewłaściwego działania” jest definiowany jako utrzymywanie niezwolnionej częściowej blokady uśpienia przez co najmniej 2 godziny średnio przy wyłączonym ekranie w ponad 5% sesji użytkownikówciągu ostatnich 28 dni. Wyjątkiem jest blokada uśpienia systemu, która przynosi użytkownikowi wyraźne korzyści, których nie można dalej optymalizować, np. odtwarzanie dźwięku, dostęp do lokalizacji lub przesyłanie danych zainicjowane przez użytkownika. Pełną definicję nadmiernych blokad uśpienia znajdziesz w dokumentacji Android Vitals.

W ramach naszych ciągłych działań na rzecz wydłużenia czasu pracy baterii w ekosystemie Androida przeanalizowaliśmy tysiące aplikacji i sposób, w jaki korzystają one z częściowych blokad wybudzania. Blokady wybudzania są czasami niezbędne, ale często widzimy, że aplikacje używają ich nieefektywnie lub niepotrzebnie, mimo że istnieją bardziej wydajne rozwiązania. W tym artykule na blogu omówimy najczęstsze scenariusze, w których występuje nadmierna liczba blokad uśpienia, oraz nasze zalecenia dotyczące optymalizacji blokad uśpienia.  Widzimy już wymierne sukcesy partnerów takich jak WHOOP, którzy wykorzystali te rekomendacje do optymalizacji działania w tle.

Korzystanie z usługi działającej na pierwszym planie a częściowe blokady wybudzania

Często widzimy, że deweloperzy mają problem z rozróżnieniem 2 pojęć związanych z wykonywaniem w tle: usługi na pierwszym planie i częściowego blokowania wybudzania.

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 być zamykana w celu odzyskania pamięci. Nie zapobiega jednak automatycznie przejściu procesora w stan uśpienia po wyłączeniu ekranu. Z kolei częściowa blokada uśpienia to mechanizm zaprojektowany specjalnie po to, aby procesor działał nawet wtedy, gdy ekran jest wyłączony.

Usługa na pierwszym planie jest często niezbędna do kontynuowania działania użytkownika, ale 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. Nie musisz też używać blokady uśpienia, jeśli korzystasz już z interfejsu API, który utrzymuje urządzenie w stanie aktywności. 

Zapoznaj się z diagramem w artykule Wybór odpowiedniego interfejsu API, który zapobiega przechodzeniu urządzenia w stan uśpienia, aby dobrze zrozumieć, jakiego narzędzia używać, aby uniknąć uzyskiwania blokady uśpienia w sytuacjach, w których nie jest to konieczne.

Biblioteki innych firm uzyskujące blokady wybudzania

Często zdarza się, że aplikacja wykrywa, że jest oznaczona z powodu nadmiernej liczby blokad wybudzania utrzymywanych przez pakiet SDK innej firmy lub interfejs API systemu działający w jej imieniu. Aby wykryć i rozwiązać problemy z blokadami wybudzania, wykonaj te czynności:

  • Sprawdź Android Vitals: znajdź dokładną nazwę problematycznej blokady uśpienia na panelu nadmiernych częściowych blokad uśpienia. Porównaj tę nazwę ze wskazówkami w sekcji 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 jest, być może musisz zoptymalizować korzystanie z interfejsu API. W tym celu możesz zapoznać się z zalecanymi wskazówkami.
  • Przechwyć ślad systemu: Jeśli blokada uśpienia nie może być łatwo zidentyfikowana, odtwórz problem z blokadą uśpienia lokalnie, korzystając ze śladu systemu, i zbadaj go za pomocą interfejsu Perfetto. Więcej informacji o tym, jak to zrobić, znajdziesz w sekcji Debugowanie innych typów nadmiernych blokad wybudzania w tym poście na blogu.
  • Ocena alternatywnych rozwiązań: jeśli problem powoduje nieefektywna biblioteka innej firmy, której nie można skonfigurować tak, aby nie wpływała negatywnie na żywotność baterii, rozważ zgłoszenie problemu właścicielom pakietu SDK, znalezienie alternatywnego pakietu SDK lub samodzielne opracowanie tej funkcji.

Typowe scenariusze blokady uśpienia

Poniżej znajdziesz zestawienie niektórych konkretnych przypadków użycia, które przeanalizowaliśmy, wraz z zalecaną ścieżką optymalizacji implementacji blokady uśpienia.

Przesyłanie lub pobieranie inicjowane przez użytkownika

Przykłady zastosowania:

  • Aplikacje do odtwarzania strumieniowego 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 uruchamia przesyłanie najnowszych zdjęć za pomocą powiadomienia.

Jak ograniczyć blokady uśpienia: 

Jednorazowa lub okresowa synchronizacja w tle

Przykłady zastosowania:

  • Aplikacja okresowo synchronizuje dane w tle, aby można było uzyskać do nich dostęp offline. 
  • aplikacje do pomiaru kroków, które okresowo pobierają liczbę kroków;

Jak ograniczyć blokady uśpienia:

  • Nie uzyskuj ręcznej blokady uśpienia. Użyj biblioteki WorkManager skonfigurowanej do jednorazowego lub okresowego wykonywania pracy. WorkManager dba o kondycję systemu, grupując zadania i ustalając minimalny okresowy interwał (15 minut), który jest zwykle wystarczający w przypadku aktualizacji w tle. 
  • Jeśli zidentyfikujesz blokady uśpienia utworzone przez WorkManager lub JobScheduler, które są często używane, może to oznaczać, że worker jest nieprawidłowo skonfigurowany i nie wykonuje zadań w określonych scenariuszach. Rozważ analizę przyczyn zatrzymania pracownika, zwłaszcza jeśli często występuje wartość STOP_REASON_TIMEOUT
workManager.getWorkInfoByIdFlow(syncWorker.id)
  .collect { workInfo ->
      if (workInfo != null) {
        val stopReason = workInfo.stopReason
        logStopReason(syncWorker.id, stopReason)
      }
  }
  • Oprócz rejestrowania powodów zatrzymania pracownika zapoznaj się z naszą dokumentacją dotyczącą debugowania pracowników. Warto też zbierać i analizować ślady systemowe , aby dowiedzieć się, kiedy blokady wybudzania są uzyskiwane i zwalniane.
  • Na koniec zapoznaj się z naszym studium przypadku dotyczącym firmy WHOOP, która dzięki temu odkryła problem z konfiguracją swoich procesów roboczych i znacznie zmniejszyła wpływ blokady uśpienia.

Komunikacja Bluetooth

Przykłady zastosowania:

  • Aplikacja urządzenia towarzyszącego wyświetla prośbę 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 na urządzenie towarzyszące inicjuje przesyłanie pliku między urządzeniem mobilnym a urządzeniem Bluetooth.
  • Aplikacja urządzenia towarzyszącego okresowo aktualizuje oprogramowanie urządzenia zewnętrznego przez Bluetooth.

Jak ograniczyć blokady 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 dotyczącymi  komunikacji w tle, aby dowiedzieć się, jak prowadzić komunikację przez Bluetooth w tle. 
  • Użycie WorkManager jest często wystarczające, jeśli opóźniona komunikacja nie ma wpływu na użytkowników. 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 do fitnessu, które zapisują dane o lokalizacji w pamięci podręcznej, aby później je przesłać, np. do wyznaczania tras biegów
  • Aplikacje do dostawy jedzenia, które pobierają dane o lokalizacji z dużą częstotliwością, aby aktualizować postęp dostawy w powiadomieniu lub widżecie.

Jak ograniczyć blokady uśpienia:

  • Zapoznaj się z naszymi wskazówkami dotyczącymi optymalizacji wykorzystania lokalizacji. Aby zapewnić oszczędność baterii, rozważ wdrożenie limitów czasu, wykorzystanie grupowania żądań lokalizacji lub pasywnych aktualizacji lokalizacji.
  • Gdy poprosisz o aktualizacje lokalizacji za pomocą interfejsów API FusedLocationProvider lub LocationManager, system automatycznie wybudzi urządzenie podczas wywołania zwrotnego zdarzenia lokalizacji. Ta krótka blokada uśpienia zarządzana przez system jest wyłączona z obliczeń dotyczących nadmiernych częściowych blokad uśpienia.
  • Unikaj uzyskiwania oddzielnej, ciągłej blokady uśpienia na potrzeby buforowania danych o lokalizacji, ponieważ jest to zbędne. Zamiast tego zapisuj zdarzenia związane z lokalizacją w pamięci lub pamięci lokalnej i wykorzystuj 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 o wysokiej częstotliwości

Przykłady zastosowania:

  • aplikacje do pomiaru kroków, które pasywnie zbierają dane o krokach lub przebytej odległości; 
  • Aplikacje związane z bezpieczeństwem, które monitorują czujniki urządzenia pod kątem szybkich zmian w czasie rzeczywistym, aby udostępniać funkcje takie jak wykrywanie wypadków czy upadków.

Jak ograniczyć blokady 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 w ramach interakcji z interfejsem. Monitorowanie czujników z wysoką częstotliwością może znacznie wyczerpywać baterię ze względu na liczbę wybudzeń procesora i przetwarzania.
  • Jeśli śledzisz liczbę kroków lub przebytą odległość, zamiast używać SensorManager, korzystaj z interfejsu Recording API lub Health Connect, aby uzyskać dostęp do historycznych i zagregowanych danych o liczbie kroków na urządzeniu i rejestrować dane w sposób oszczędzający baterię.
  • Jeśli rejestrujesz czujnik za pomocą interfejsu SensorManager, określ wartość parametru maxReportLatencyUs na co najmniej 30 sekund, aby korzystać z 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, pobranie 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 zarówno danych o lokalizacji, jak i danych z czujników, zsynchronizuj pobieranie i przetwarzanie zdarzeń. Dzięki wykorzystaniu odczytów z czujników w krótkim okresie 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. Użyj procesu roboczego lub blokady uśpienia o krótkim czasie trwania, aby obsłużyć przesyłanie i przetwarzanie tych połączonych danych.

Zdalne przesyłanie wiadomości

Przykłady zastosowania:

  • 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 za pomocą sieci lokalnej.
  • Komunikatory, które utrzymują połączenie gniazda sieciowego z wersją na komputery.

Jak ograniczyć blokady uśpienia:

  • Jeśli zdarzenia sieciowe można przetwarzać po stronie serwera, użyj FCM, aby otrzymywać informacje na urządzeniu klienta. Jeśli wymagane jest dodatkowe przetwarzanie danych FCM, możesz zaplanować przyspieszone działanie
  • Jeśli zdarzenia muszą być przetwarzane po stronie klienta za pomocą połączenia gniazdowego, blokada uśpienia nie jest potrzebna do nasłuchiwania przerw w zdarzeniach. 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ć uruchomienie procesu lub uzyskać blokadę wybudzenia, 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 uzyskiwać 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

Stosując te zalecane rozwiązania w przypadku typowych przypadków użycia, takich jak synchronizacja w tle, śledzenie lokalizacji, monitorowanie czujników i komunikacja sieciowa, deweloperzy mogą ograniczyć niepotrzebne użycie blokady uśpienia. Aby dowiedzieć się więcej, przeczytaj nasz kolejny post na blogu technicznym lub obejrzyj film techniczny o tym, jak wykrywać i debugować blokady uśpienia: Optymalizowanie zużycia baterii przez aplikację za pomocą wskaźnika blokad uśpienia w Android Vitals. Zapoznaj się też z naszą zaktualizowaną dokumentacją dotyczącą blokad wybudzania. Aby pomóc nam w dalszym ulepszaniu naszych zasobów technicznych, podziel się dodatkowymi uwagami na temat naszych wskazówek w ankiecie dotyczącej dokumentacji.

Autor:

Czytaj dalej