Gdy aplikacja działa w tle, zużywa część ograniczonych zasobów urządzenia, takich jak pamięć RAM. Może to pogorszyć komfort korzystania z aplikacji, zwłaszcza jeśli użytkownik korzysta z aplikacji wymagającej dużych zasobów, np. gry lub filmu. Aby poprawić komfort korzystania z aplikacji, Android 8.0 (poziom API 26) nakłada ograniczenia na to, co aplikacje mogą robić podczas działania w tle. W tym dokumencie opisaliśmy zmiany w systemie operacyjnym i sposób zaktualizowania aplikacji, aby działała prawidłowo w ramach nowych ograniczeń.
Omówienie
Wiele aplikacji i usług na Androida może działać jednocześnie. Użytkownik może na przykład grać w jednym oknie, przeglądać internet w drugim i odtwarzać muzykę w trzeciej aplikacji. 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, obciążają one system, co może negatywnie wpływać na komfort użytkowania. Na przykład aplikacja muzyczna może się nagle zamknąć.
Aby zmniejszyć ryzyko wystąpienia 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ą ograniczane na 2 sposoby:
Ograniczenia usług w tle: gdy aplikacja jest nieaktywna, korzystanie z usług w tle jest ograniczone. Nie dotyczy to usług na pierwszym planie, które są bardziej widoczne dla użytkownika.
Ograniczenia transmisji: z nielicznymi wyjątkami aplikacje nie mogą używać pliku manifestu do rejestrowania transmisji niejawnych. Nadal mogą rejestrować się do tych transmisji w czasie ich trwania i korzystać z pliku manifestu, aby zarejestrować się do transmisji zawierających treści dla dorosłych i transmisji kierowanych konkretnie do ich aplikacji.
W większości przypadków aplikacje mogą obejść te ograniczenia, korzystając z zadań JobScheduler
. Dzięki temu aplikacja może wykonywać zadania, gdy nie jest aktywna, ale system nadal ma możliwość planowania tych zadań w sposób, który nie wpływa na komfort użytkownika. Android 8.0 wprowadza kilka ulepszeń w JobScheduler
, które ułatwiają zastępowanie usług i odbiorników rozgłoszeniowych zaplanowanymi zadaniami. Więcej informacji znajdziesz w artykule Ulepszenia w JobScheduler.
Ograniczenia działania w tle
Usługi działające w tle mogą zużywać zasoby urządzenia, co może pogorszyć komfort użytkowania. Aby ograniczyć ten problem, system nakłada na usługi szereg ograniczeń.
System rozróżnia aplikacje na pierwszym planie i 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 być w tle w odniesieniu do zarządzania pamięcią, ale na pierwszym planie w odniesieniu do możliwości uruchamiania usług). Aplikacja jest uważana za aplikację na pierwszym planie, jeśli jest spełniony jeden z tych warunków:
- Ma widoczną aktywność, niezależnie od tego, czy jest ona wstrzymana czy w trakcie wykonywania.
- Usługa działa na pierwszym planie.
- Inna aplikacja na pierwszym planie jest połączona z aplikacją, ponieważ jest powiązana z jedną z jej usług lub korzysta z jednego z jej dostawców treści. Aplikacja jest na pierwszym planie, jeśli inna aplikacja łączy się z jej:
- IME
- Usługa tapety
- Odbiornik powiadomień
- Usługa głosowa lub tekstowa
Jeśli żaden z tych warunków nie jest spełniony, aplikacja jest uważana za działającą w tle.
Gdy aplikacja działa na pierwszym planie, może swobodnie tworzyć i uruchamiać usługi na pierwszym i tylnym planie. Gdy aplikacja przechodzi do działania w tle, ma kilka minut na tworzenie i używanie usług. Na koniec tego okna aplikacja jest uważana za nieaktywną. W tym momencie system zatrzymuje usługi w tle aplikacji tak, jakby aplikacja wywołała metody Service.stopSelf()
tych usług.
W niektórych okolicznościach aplikacja działająca w tle jest tymczasowo umieszczana na liście dozwolonych przez kilka minut. 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 wykonuje zadanie widoczne dla użytkownika, takie jak:
- Obsługa wiadomości o wysokiej priorytecie wysłanej przez Komunikację w chmurze Firebase (FCM).
- Odbieranie transmisji, np. SMS-a lub MMS-a.
- Wykonywanie czynności
PendingIntent
z poziomu powiadomienia. - Uruchomienie
VpnService
przed tym, jak aplikacja VPN przeniesie się na pierwszy plan.
W wielu przypadkach aplikacja może zastąpić usługi działające w tle zadaniami JobScheduler
.
Na przykład aplikacja CoolPhotoApp musi sprawdzić, czy użytkownik otrzymał udostępnione zdjęcia od znajomych, nawet jeśli aplikacja nie działa na pierwszym planie. Wcześniej aplikacja używała usługi w tle, która sprawdzała pamięć masową w chmurze aplikacji. Aby przejść na Androida 8.0 (interfejs API na poziomie 26), deweloper zastępuje usługę w tle zaplanowanym zadaniem, które jest okresowo uruchamiane, wysyła zapytanie do serwera, a potem się zamyka.
Przed Androidem 8.0 zwykle tworzyło się usługę na pierwszym planie, tworząc najpierw usługę działającą w tle, a potem przenosząc ją na pierwszy plan.
W przypadku Androida 8.0 występuje pewien problem: system nie zezwala aplikacji działającej w tle na tworzenie usług działających w tle. Dlatego w Androidzie 8.0 wprowadzamy nową metodę startForegroundService()
, która umożliwia uruchamianie nowej usługi na pierwszym planie. Gdy system utworzy usługę, aplikacja ma 5 sekund na wywołanie metody [startForeground()
](/reference/android/app/Service#startForeground(int, android.app.Notification) usługi, aby wyświetlić widoczne dla użytkownika powiadomienie. Jeśli aplikacja nie wywoła startForeground()
w określonym czasie, system zatrzyma usługę i ogłosi, że aplikacja jest ANR.
Ograniczenia transmisji
Jeśli aplikacja rejestruje się, aby odbierać transmisje, odbiornik aplikacji zużywa zasoby za każdym razem, gdy transmisja jest wysyłana. Może to powodować problemy, jeśli zbyt wiele aplikacji zarejestruje się do odbioru transmisji na podstawie zdarzeń systemowych. Zdarzenie systemowe, które powoduje transmisję, może spowodować, że wszystkie te aplikacje będą szybko zużywać zasoby, co pogorszy komfort użytkownika. Aby rozwiązać ten problem, w Androidzie 7.0 (interfejs API na poziomie 24) wprowadzono ograniczenia dotyczące transmisji, jak opisano w artykule Background Optimization. W Androidzie 8.0 (poziom 26 interfejsu API) te ograniczenia są bardziej rygorystyczne.
- Aplikacje kierowane na Androida 8.0 lub nowszego nie mogą już rejestrować odbiorników transmisji w manifeście w przypadku transmisji niejawnych, chyba że transmisja jest ograniczona do tej konkretnej aplikacji. Wyłączenie pośrednie to wyłączenie, które nie jest kierowane do konkretnego komponentu w aplikacji. Na przykład
ACTION_PACKAGE_REPLACED
jest wysyłane do wszystkich zarejestrowanych słuchaczy we wszystkich aplikacjach, aby poinformować ich o tym, że na urządzeniu został zastąpiony jakiś pakiet. Ponieważ jest to transmisja niejawna, nie będzie dostarczana odbiorcom zarejestrowanym w manifeście w aplikacjach kierowanych na Androida 8.0 lub nowszego.ACTION_MY_PACKAGE_REPLACED
jest również niejawnym rozgłoszeniem, ale ponieważ jest wysyłany tylko do aplikacji, której pakiet został zastąpiony, zostanie dostarczony odbiorcom zarejestrowanym w pliku manifestu. - Aplikacje nadal mogą rejestrować się do transmisji treści dla dorosłych w swoich plikach manifestu.
- Aplikacje mogą używać
Context.registerReceiver()
w czasie działania, aby zarejestrować odbiornik dla dowolnej transmisji, czy to domyślnej, czy jawnej. - Transmisje, które wymagają uprawnienia do podpisywania, są wyłączone 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, które wcześniej zarejestrowały się do transmisji za pomocą funkcji biernego przesyłania, mogą uzyskać podobne funkcje, korzystając z zadania JobScheduler
.
Na przykład aplikacja do zdjęć społecznościowych może od czasu do czasu potrzebować oczyszczenia danych i najchętniej robi to, gdy urządzenie jest podłączone do ładowarki.
Wcześniej aplikacja rejestrowała w swoim pliku manifestu odbiornik dla ACTION_POWER_CONNECTED
. Gdy aplikacja otrzymywała tę transmisję, sprawdzała, czy konieczne jest wyczyszczenie. Aby przejść na Androida 8.0 lub nowszego, aplikacja usuwa tego odbiornika z pliku manifestu. Zamiast tego aplikacja planuje zadanie czyszczenia, które jest wykonywane, gdy urządzenie jest nieaktywne i ładowane.
Przewodnik po migracji
Domyślnie te zmiany dotyczą tylko aplikacji kierowanych na Androida 8.0 (poziom interfejsu API 26) lub nowszego. Użytkownicy mogą jednak włączyć te ograniczenia w dowolnej aplikacji na ekranie Ustawienia, nawet jeśli aplikacja jest przeznaczona dla poziomu interfejsu API niższego niż 26. Konieczne może być zaktualizowanie aplikacji, aby spełniała nowe ograniczenia.
Sprawdź, jak aplikacja korzysta z usług. Jeśli aplikacja korzysta z usług działających w tle, gdy jest nieaktywna, 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 metodystartService()
. - Jeśli usługa jest zauważalna dla użytkownika, uczyń ją usługą na pierwszym planie. Na przykład usługa odtwarzająca dźwięk powinna zawsze być usługą na pierwszym planie.
Utwórz usługę za pomocą metody
startForegroundService()
zamiast metodystartService()
. - Znajdź sposób na powielenie funkcji usługi za pomocą zaplanowanego zadania. Jeśli usługa nie wykonuje czynności, która jest natychmiast widoczna dla użytkownika, możesz zamiast tego użyć zaplanowanego zadania.
- Używaj FCM, aby wybiórczo aktywować aplikację, gdy występują zdarzenia sieciowe, zamiast przeprowadzać cykliczne zapytania w tle.
- Opóźnij działanie w tle do momentu, gdy aplikacja będzie działać na pierwszym planie.
Sprawdź odbiorniki transmisji strumieniowej zdefiniowane w pliku manifestu aplikacji. Jeśli manifest deklaruje odbiornik dla dotkniętego problemu w przypadku transmisji domyślnej, musisz go zastąpić. Możliwe rozwiązania:
- Utwórz odbiornik w czasie wykonywania, wywołując
Context.registerReceiver()
, zamiast deklarować go w pliku manifestu. - Użyj zaplanowanego zadania, aby sprawdzić, czy warunek, który spowodował niejawne rozpowszechnianie, został spełniony.