Limity wykonywania w tle

Gdy aplikacja działa w tle, zużywa niektóre ograniczone zasoby urządzenia, takie jak pamięć RAM. Może to utrudniać korzystanie z aplikacji, zwłaszcza jeśli używa aplikacji, które zużywają dużo zasobów, np. grają w grę lub oglądają filmy. Aby zwiększyć wygodę użytkowników, Android 8.0 (poziom interfejsu API 26) nakłada ograniczenia na możliwości aplikacji działających w tle. Ten dokument zawiera informacje o zmianach w systemie operacyjnym i o tym, jak zaktualizować aplikację, aby działała prawidłowo w ramach nowych ograniczeń.

Przegląd

Jednocześnie może działać wiele aplikacji i usług na Androida. Na przykład użytkownik może grać w grę w jednym oknie, a jednocześnie przeglądać internet w innym oknie, a potem używać trzeciej aplikacji do odtwarzania muzyki. Im więcej aplikacji działa jednocześnie, tym większe obciążenie systemu. Jeśli dodatkowe aplikacje lub usługi działają w tle, zwiększa to obciążenie systemu, co może negatywnie wpłynąć na komfort użytkowania. Może to na przykład dotyczyć nagłego wyłączenia aplikacji muzycznej.

Aby zmniejszyć ryzyko tych problemów, Android 8.0 nakłada ograniczenia na to, co aplikacje mogą robić, gdy użytkownicy nie wchodzą z nimi w bezpośrednią interakcję. Aplikacje są ograniczone na 2 sposoby:

  • Ograniczenia usług w tle: gdy aplikacja jest nieaktywna, obowiązują pewne ograniczenia w zakresie jej usług. Nie dotyczy to usług działających na pierwszym planie, które są bardziej widoczne dla użytkownika.

  • Ograniczenia transmisji: z pewnymi nielicznymi wyjątkami aplikacje nie mogą używać pliku manifestu do rejestrowania komunikatów niejawnych. Mogą oni nadal rejestrować się na potrzeby tych transmisji w czasie ich działania oraz używać pliku manifestu do rejestrowania komunikatów dla pełnoletnich i kierowanych na ich aplikację.

W większości przypadków aplikacje mogą obejść te ograniczenia, używając zadań JobScheduler. Takie podejście umożliwia aplikacji wykonywanie zadań, gdy nie jest aktywnie uruchomiona, ale daje systemowi możliwość planowania tych zadań w sposób, który nie wpływa na wygodę użytkowników. Android 8.0 oferuje kilka ulepszeń w JobScheduler, które ułatwiają zastępowanie usług i odbiorników transmisji zaplanowanymi zadaniami. Więcej informacji znajdziesz w artykule o ulepszeniach JobScheduler.

Ograniczenia usług w tle

Usługi działające w tle mogą zużywać zasoby urządzenia, co może pogorszyć wrażenia użytkowników. Aby temu zaradzić, system nakłada na usługi szereg ograniczeń.

System odróżnia aplikacje pierwszego planu od aplikacji w tle. Definicja tła na potrzeby ograniczeń usługi różni się od definicji używanej przez zarządzanie pamięcią – aplikacja może działać w tle, co dotyczy zarządzania pamięcią, ale na pierwszym planie (w związku z możliwością uruchamiania usług). Aplikacja jest uznawana za działającą na pierwszym planie, jeśli jest spełniony dowolny z tych warunków:

  • Widoczna jest aktywność niezależnie od tego, czy została rozpoczęta czy wstrzymana.
  • Ma usługę na pierwszym planie.
  • Z aplikacją łączy się inna aplikacja na pierwszym planie przez powiązanie z jedną z jej usług lub korzystanie z usług jednego z dostawców treści. Na przykład aplikacja jest na pierwszym planie, jeśli inna aplikacja jest powiązana ze swoim:
    • IME
    • Tapety
    • Odbiornik powiadomień
    • Usługa połączeń głosowych lub SMS-ów

Jeśli żaden z tych warunków nie jest spełniony, aplikacja jest uznawana za działającą w tle.

Gdy aplikacja działa na pierwszym planie, może swobodnie tworzyć i uruchamiać zarówno usługi na pierwszym planie, jak i w tle. Gdy aplikacja przechodzi w tle, przez kilka minut może nadal tworzyć i korzystać z usług. Pod koniec tego okna aplikacja zostanie uznana za bezczynną. W tym momencie system zatrzymuje usługi w tle aplikacji, tak jakby aplikacja wywołała metody Service.stopSelf() tych usług.

W pewnych okolicznościach aplikacja w tle jest na kilka minut umieszczana na tymczasowej liście dozwolonych. Gdy aplikacja znajduje się na liście dozwolonych, może uruchamiać usługi bez ograniczeń, a jej usługi w tle mogą działać. Aplikacja jest umieszczana na liście dozwolonych, gdy obsługuje zadania widoczne dla użytkownika, na przykład:

W wielu przypadkach aplikacja może zastąpić usługi w tle zadaniami JobScheduler. Na przykład CoolPhotoApp musi sprawdzić, czy użytkownik otrzymał zdjęcia udostępnione od znajomych, nawet jeśli aplikacja nie działa na pierwszym planie. Wcześniej aplikacja korzystała w tle z usługi, która sprawdzała ilość miejsca w chmurze. Aby przejść na Androida 8.0 (poziom interfejsu API 26), deweloper zastępuje usługę w tle zaplanowanym zadaniem, które jest uruchamiane okresowo, odpytuje serwer, a następnie go zamyka.

Przed wersjami z Androidem 8.0 typowym sposobem tworzenia usługi na pierwszym planie było utworzenie usługi działającej w tle i wypromowania jej na pierwszy plan. W Androidzie 8.0 występuje pewien komplikacja: system nie zezwala aplikacji działającej w tle na utworzenie usługi w tle. Z tego powodu w Androidzie 8.0 wprowadziliśmy nową metodę (startForegroundService()), która uruchamia nową usługę na pierwszym planie. Po utworzeniu usługi przez system aplikacja ma 5 sekund na wywołanie metody [startForeground()](/reference/android/app/Service#startForeground(int, android.app.notification) w celu wyświetlenia widocznego dla użytkownika powiadomienia nowej usługi. Jeśli aplikacja nie wywoła funkcji startForeground() w wyznaczonym czasie, system zatrzyma usługę i oznaczy aplikację jako ANR.

Ograniczenia transmisji

Jeśli aplikacja zarejestruje się, by odbierać komunikaty, jej odbiorca wykorzystuje zasoby za każdym razem, gdy jest wysyłana. Może to powodować problemy, jeśli rejestruje się zbyt wiele aplikacji, aby odbierać komunikaty związane ze zdarzeniami systemowymi. Zdarzenie systemowe, które wywołuje transmisję, może spowodować szybkie zużywanie zasobów przez wszystkie aplikacje, co negatywnie wpływa na wygodę użytkowników. Aby rozwiązać ten problem, Android 7.0 (poziom interfejsu API 24) nałożył ograniczenia na transmisje zgodnie z opisem w sekcji Optymalizacja w tle. W Androidzie 8.0 (poziom interfejsu API 26) te ograniczenia są bardziej rygorystyczne.

  • Aplikacje kierowane na Androida 8.0 lub nowszego nie mogą już rejestrować odbiorców transmisji niejawnych w pliku manifestu, chyba że transmisja jest ograniczona do konkretnej aplikacji. Komunikaty niejawne to transmisja, która nie jest kierowana na określony komponent aplikacji. Na przykład zapis ACTION_PACKAGE_REPLACED jest wysyłany do wszystkich zarejestrowanych słuchaczy we wszystkich aplikacjach, co informuje ich, że jakiś pakiet na urządzeniu został zastąpiony. Komunikaty są niejawne, dlatego nie zostaną dostarczone do odbiorców zarejestrowanych w pliku manifestu w aplikacjach kierowanych na Androida 8.0 lub nowszego. ACTION_MY_PACKAGE_REPLACED jest też komunikatem niejawnym, ale ponieważ jest wysyłana tylko do aplikacji, której pakiet został zastąpiony, zostanie dostarczony do odbiorców zarejestrowanych w pliku manifestu.
  • Aplikacje nadal mogą rejestrować komunikaty dla pełnoletnich w plikach manifestu.
  • Aplikacje mogą używać Context.registerReceiver() w czasie działania do rejestrowania odbiornika w przypadku dowolnej transmisji, zarówno niejawnej, jak i jawnej.
  • Transmisje, które wymagają uprawnień do podpisu, są zwolnione z tego ograniczenia, ponieważ są wysyłane tylko do aplikacji podpisanych tym samym certyfikatem, a nie do wszystkich aplikacji na urządzeniu.

W wielu przypadkach aplikacje zarejestrowane wcześniej na potrzeby komunikatów niejawnych mogą uzyskać podobne funkcje, wykorzystując zadanie JobScheduler. Na przykład aplikacja do obsługi zdjęć społecznościowych może od czasu do czasu czyścić swoje dane, ale preferuje to, gdy urządzenie jest podłączone do ładowarki. Wcześniej aplikacja rejestrowała w swoim manifeście odbiornika ACTION_POWER_CONNECTED. Gdy aplikacja otrzymała tę transmisję, sprawdzała, czy trzeba wyczyścić dane. Aby przejść na Androida 8.0 lub nowszego, aplikacja usuwa tego odbiornika z pliku manifestu. Zamiast tego aplikacja planuje zadanie czyszczenia, które jest uruchamiane, gdy urządzenie jest bezczynne i się ładuje.

Przewodnik po migracji

Domyślnie te zmiany dotyczą tylko aplikacji kierowanych na Androida 8.0 (poziom API 26) lub nowszego. Użytkownicy mogą jednak włączyć te ograniczenia dla dowolnej aplikacji na ekranie Ustawienia, nawet jeśli aplikacja jest kierowana na poziom interfejsu API niższy niż 26. Konieczna może być aktualizacja aplikacji, aby była zgodna z nowymi ograniczeniami.

Sprawdź, jak Twoja aplikacja korzysta z usług. Jeśli Twoja aplikacja korzysta z usług, które działają w tle, gdy jest bezczynna, musisz je zastąpić. Możliwe rozwiązania:

  • Jeśli aplikacja musi utworzyć usługę na pierwszym planie, gdy działa w tle, użyj metody startForegroundService() zamiast startService().
  • Jeśli użytkownik widzi usługę, ustaw ją jako usługę na pierwszym planie. Na przykład usługa, która odtwarza dźwięk, powinna zawsze być usługą na pierwszym planie. Utwórz usługę za pomocą metody startForegroundService() zamiast startService().
  • Znajdź sposób na zduplikowanie działania usługi za pomocą zaplanowanego zadania. Jeśli usługa nie wykonuje działania widocznego dla użytkownika, użycie zaplanowanego zadania powinno być możliwe.
  • Używaj FCM, aby selektywnie uruchamiać aplikację po wystąpieniu zdarzeń sieciowych, zamiast przeprowadzać sondowanie w tle.
  • Odrocz pracę w tle, dopóki aplikacja nie znajdzie się na pierwszym planie.

Sprawdź odbiorników zdefiniowanych w pliku manifestu aplikacji. Jeśli w pliku manifestu deklaruje się odbiornika niejawnej transmisji, której dotyczy problem, musisz go zastąpić. Możliwe rozwiązania:

  • Zamiast deklarować odbiorcę w pliku manifestu, utwórz go w czasie działania, wywołując metodę Context.registerReceiver().
  • Za pomocą zaplanowanego zadania sprawdź warunek, który spowodowałby uruchomienie komunikatu pośredniego.