Aplikacje często muszą wykonywać więcej niż jedną czynność naraz. Interfejsy API Androida oferują wiele różnych sposobów, aby to zrobić. Wybór odpowiedniej opcji jest bardzo ważny. Opcja, która jest odpowiednia w jednej sytuacji, może być zupełnie nieodpowiednia w innej. Wybór niewłaściwych interfejsów API może negatywnie wpłynąć na wydajność aplikacji lub efektywność wykorzystania zasobów, co może powodować rozładowywanie baterii i pogorszenie wydajności urządzenia użytkownika. W niektórych przypadkach wybór niewłaściwego podejścia może uniemożliwić umieszczenie aplikacji w Sklepie Play.
W tym dokumencie opisujemy różne dostępne opcje i pomagamy wybrać tę, która najlepiej pasuje do Twojej sytuacji.
Terminologia
Niektóre ważne terminy związane z zadaniem w tle mogą być używane na wiele sprzecznych sposobów. Dlatego ważne jest, aby zdefiniować nasze warunki.
Jeśli aplikacja działa w tle, system nakłada na nią szereg ograniczeń. (na przykład w większości przypadków aplikacja działająca w tle nie może uruchamiać usług na pierwszym planie).
W tym dokumencie termin „zadanie” oznacza operację, którą aplikacja wykonuje poza głównym przepływem pracy. Aby ułatwić zrozumienie, podzieliliśmy je na 3 główne kategorie: praca asynchroniczna, interfejsy API do planowania zadań i usługi na pierwszym planie.
Wybierz odpowiednią opcję
W większości przypadków możesz określić odpowiednie interfejsy API do użycia w zadaniu, określając kategorię (praca asynchroniczna, interfejsy API do planowania zadań lub usługi działające na pierwszym planie), do której należy zadanie.
Jeśli nadal masz wątpliwości, możesz skorzystać z naszych schematów blokowych, które zawierają więcej szczegółów ułatwiających podjęcie decyzji. Każda z tych opcji została szczegółowo opisana w dalszej części tego dokumentu.
W przypadku zadań w tle należy wziąć pod uwagę 2 główne scenariusze:
- Zadanie zainicjowane przez użytkownika, gdy aplikacja jest widoczna
- Zadanie jest inicjowane w odpowiedzi na zdarzenie wewnętrzne lub zewnętrzne.
Te 2 scenariusze mają własne drzewa decyzyjne.
Praca asynchroniczna
W wielu przypadkach aplikacja musi wykonywać operacje równoległe tylko wtedy, gdy działa na pierwszym planie. Na przykład aplikacja może potrzebować wykonać czasochłonne obliczenia. Gdyby obliczenia były wykonywane w wątku UI, użytkownik nie mógłby korzystać z aplikacji, dopóki obliczenia nie zostałyby zakończone. Mogłoby to spowodować błąd ANR. W takim przypadku aplikacja powinna używać opcji pracy asynchronicznej.
Typowe opcje pracy asynchronicznej obejmują współprogramy Kotlin i wątki Java. Więcej informacji znajdziesz w dokumentacji pracy asynchronicznej. Warto zauważyć, że w przeciwieństwie do interfejsów API zadań w tle nie ma gwarancji, że zadanie asynchroniczne zostanie ukończone, jeśli aplikacja przestanie być na prawidłowym etapie cyklu życia (np. jeśli aplikacja opuści pierwszy plan).
Interfejsy API do planowania zadań
Interfejsy API do planowania zadań są bardziej elastyczną opcją, gdy musisz wykonywać zadania, które muszą być kontynuowane, nawet jeśli użytkownik opuści aplikację. W większości przypadków najlepszą opcją do wykonywania zadań w tle jest użycie WorkManagera, chociaż w niektórych przypadkach może być odpowiednie użycie interfejsu API platformy JobScheduler.
WorkManager to zaawansowana biblioteka, która pozwala konfigurować proste lub skomplikowane zadania zgodnie z potrzebami. Za pomocą biblioteki WorkManager możesz planować zadania do wykonania w określonych godzinach lub określać warunki, w których zadanie ma zostać wykonane. Możesz nawet skonfigurować łańcuchy zadań, aby każde zadanie było uruchamiane po kolei i przekazywało wyniki do następnego. Aby poznać wszystkie dostępne opcje, zapoznaj się z listą funkcji WorkManagera.
Oto kilka najczęstszych scenariuszy dotyczących zadań w tle:
- Okresowe pobieranie danych z serwera
- pobieranie danych z czujników (np. danych z licznika kroków);
- pobieranie okresowych danych o lokalizacji (na Androidzie 10 lub nowszym musisz mieć uprawnienie
ACCESS_BACKGROUND_LOCATION); - przesyłanie treści na podstawie aktywatora treści, np. zdjęć utworzonych przez aparat;
Usługi działające na pierwszym planie
Usługi na pierwszym planie to skuteczny sposób na natychmiastowe uruchamianie zadań, których nie należy przerywać. Jednak usługi na pierwszym planie mogą potencjalnie mocno obciążać urządzenie, a czasami mają wpływ na prywatność i bezpieczeństwo. Z tego powodu system nakłada wiele ograniczeń na to, jak i kiedy aplikacje mogą korzystać z usług na pierwszym planie. Na przykład usługa na pierwszym planie musi być zauważalna dla użytkownika i w większości przypadków aplikacje nie mogą uruchamiać usług na pierwszym planie, gdy działają w tle. Więcej informacji znajdziesz w dokumentacji usług działających na pierwszym planie.
Usługę działającą na pierwszym planie można utworzyć na 2 sposoby. Możesz zadeklarować własną klasę Service i określić, że usługa jest usługą działającą na pierwszym planie, wywołując metodę Service.startForeground(). Możesz też użyć biblioteki WorkManager, aby utworzyć usługę na pierwszym planie, zgodnie z opisem w sekcji Obsługa długotrwałych procesów roboczych.
Należy jednak pamiętać, że usługa na pierwszym planie utworzona przez WorkManager musi podlegać tym samym ograniczeniom co każda inna usługa na pierwszym planie.
WorkManager udostępnia tylko kilka wygodnych interfejsów API, które ułatwiają tworzenie usługi działającej na pierwszym planie.
Alternatywne interfejsy API
System oferuje alternatywne interfejsy API, które są zaprojektowane tak, aby działać lepiej w przypadku bardziej konkretnych zastosowań. Jeśli w Twoim przypadku istnieje alternatywny interfejs API, zalecamy użycie go zamiast usługi na pierwszym planie, ponieważ powinno to pomóc w poprawie wydajności aplikacji. W dokumentacji typów usług na pierwszym planie znajdziesz informacje o tym, kiedy zamiast określonego typu usługi na pierwszym planie można użyć odpowiedniego interfejsu API.
Oto niektóre z najczęstszych scenariuszy użycia alternatywnych interfejsów API:
- używanie przesyłania danych inicjowanego przez użytkownika do przesyłania lub pobierania dużych plików zamiast tworzenia usługi na pierwszym planie do synchronizacji danych;
- Używanie menedżera urządzeń towarzyszących do parowania Bluetooth i przesyłania danych zamiast usługi na pierwszym planie na połączonym urządzeniu.
- używanie trybu obrazu w obrazie do odtwarzania filmów zamiast tworzenia usługi odtwarzania multimediów na pierwszym planie;
Zadania zainicjowane przez użytkownika
Jeśli aplikacja musi wykonywać zadania w tle, a operacja jest inicjowana przez użytkownika, gdy aplikacja jest widoczna, odpowiedz na te pytania, aby znaleźć właściwe rozwiązanie.
Czy zadanie musi być nadal wykonywane, gdy aplikacja działa w tle?
Jeśli zadanie nie musi być kontynuowane, gdy aplikacja działa w tle, użyj pracy asynchronicznej. Istnieje kilka opcji wykonywania pracy asynchronicznej. Ważne jest, aby zrozumieć, że wszystkie te opcje przestają działać, gdy aplikacja przechodzi w tło. (Zatrzymują się też, gdy aplikacja zostanie zamknięta). Na przykład aplikacja społecznościowa może chcieć odświeżyć źródło treści, ale nie musi kończyć tej operacji, jeśli użytkownik opuści ekran.
Czy odroczenie lub przerwanie zadania będzie miało negatywny wpływ na wrażenia użytkownika?
Warto zastanowić się, czy odłożenie lub anulowanie zadania nie wpłynie negatywnie na wrażenia użytkownika. Jeśli na przykład aplikacja musi zaktualizować swoje zasoby, użytkownik może nie zauważyć, czy operacja odbywa się od razu, czy w środku nocy, gdy urządzenie się ładuje. W takich przypadkach należy użyć opcji pracy w tle.
Czy jest to krótkie, kluczowe zadanie?
Jeśli zadania nie można opóźnić i zostanie ono szybko ukończone, możesz użyć usługi na pierwszym planie typu shortService. Te usługi są łatwiejsze do utworzenia niż inne usługi na pierwszym planie i nie wymagają tylu uprawnień. Jednak krótkie usługi muszą zakończyć się w ciągu 3 minut.
Czy istnieje alternatywny interfejs API przeznaczony tylko do tego celu?
Jeśli zadanie nie jest niewidoczne dla użytkownika, prawidłowym rozwiązaniem może być użycie usługi na pierwszym planie. Te usługi działają nieprzerwanie po uruchomieniu, więc są dobrym wyborem, gdy przerwanie zadania mogłoby negatywnie wpłynąć na wrażenia użytkownika. Na przykład aplikacja do śledzenia treningów może używać czujników lokalizacji, aby umożliwić użytkownikom zapisywanie trasy joggingu na mapie. Nie chcesz tego robić z opcją pracy w tle, ponieważ jeśli zadanie zostanie wstrzymane, śledzenie natychmiast się zatrzyma. W takiej sytuacji usługa na pierwszym planie jest najbardziej odpowiednia.
Ponieważ jednak usługi działające na pierwszym planie mogą potencjalnie zużywać dużo zasobów urządzenia, system nakłada wiele ograniczeń dotyczących tego, kiedy i jak można z nich korzystać. W wielu przypadkach zamiast usługi na pierwszym planie możesz użyć alternatywnego interfejsu API, który wykona zadanie z mniejszymi problemami. Jeśli na przykład aplikacja musi wykonać działanie, gdy użytkownik dotrze do określonej lokalizacji, najlepiej użyć interfejsu Geofence API, zamiast śledzić lokalizację użytkownika za pomocą usługi na pierwszym planie.
Zadania w odpowiedzi na zdarzenie
Czasami aplikacja musi wykonać pracę w tle w odpowiedzi na aktywator, np.:
- Wysyłanie komunikatów
- Wiadomości Komunikacji w chmurze Firebase (FCM)
- alarmy ustawione przez aplikację,
Może to być aktywator zewnętrzny (np. wiadomość FCM) lub odpowiedź na alarm ustawiony przez samą aplikację. Na przykład gra może otrzymać wiadomość FCM z informacją o konieczności zaktualizowania niektórych zasobów.
Jeśli masz pewność, że zadanie zakończy się w ciągu kilku sekund, użyj pracy asynchronicznej. System pozwoli aplikacji na wykonywanie takich zadań przez kilka sekund, nawet jeśli działa ona w tle.
Jeśli zadanie będzie trwało dłużej niż kilka sekund, warto uruchomić usługę działającą na pierwszym planie, która je obsłuży. Nawet jeśli aplikacja działa obecnie w tle, może mieć uprawnienia do uruchomienia usługi na pierwszym planie, jeśli zadanie zostało wywołane przez użytkownika i jest objęte jednym z zatwierdzonych wyjątków od ograniczeń dotyczących uruchamiania w tle. Jeśli na przykład aplikacja otrzyma wiadomość FCM o wysokim priorytecie, może uruchomić usługę działającą na pierwszym planie, nawet jeśli działa w tle.
Jeśli zadanie potrwa dłużej niż kilka sekund, użyj interfejsów API do planowania zadań.