Tworzenie usług systemu Android

W tym przewodniku omówiono usługi platformy Xamarin.Android, które są składnikami systemu Android, które umożliwiają wykonywanie pracy bez aktywnego interfejsu użytkownika. Usługi są bardzo często używane w przypadku zadań wykonywanych w tle, takich jak czasochłonne obliczenia, pobieranie plików, odtwarzanie muzyki itd. Wyjaśniono w nim różne scenariusze, dla których są odpowiednie usługi, oraz pokazano, jak zaimplementować je zarówno do wykonywania długotrwałych zadań w tle, jak i do udostępniania interfejsu dla zdalnych wywołań procedur.

Omówienie usług systemu Android

Aplikacje mobilne nie są takie jak aplikacje klasyczne. Komputery stacjonarne mają dużą ilość zasobów, takich jak nieruchomości ekranu, pamięć, miejsce do magazynowania i podłączony zasilacz, urządzenia przenośne nie. Te ograniczenia wymuszają zachowanie aplikacji mobilnych w inny sposób. Na przykład mały ekran na urządzeniu przenośnym zwykle oznacza, że tylko jedna aplikacja (tj. Działanie) jest widoczna naraz. Inne działania są przenoszone do tła i wypychane do stanu zawieszonego, w którym nie mogą wykonywać żadnej pracy. Jednak tylko dlatego, że aplikacja dla systemu Android znajduje się w tle, nie oznacza, że nie można kontynuować pracy aplikacji.

Aplikacje systemu Android składają się z co najmniej jednego z następujących czterech podstawowych składników: działania, odbiorniki emisji, dostawcy zawartości i usługi. Działania są podstawą wielu wspaniałych aplikacji systemu Android, ponieważ zapewniają interfejs użytkownika, który umożliwia użytkownikowi interakcję z aplikacją. Jednak jeśli chodzi o wykonywanie współbieżnych lub w tle pracy, działania nie zawsze są najlepszym wyborem.

Podstawowym mechanizmem pracy w tle w systemie Android jest usługa. Usługa systemu Android to składnik, który jest przeznaczony do wykonywania niektórych czynności bez interfejsu użytkownika. Usługa może pobrać plik, odtworzyć muzykę lub zastosować filtr do obrazu. Usługi mogą być również używane do komunikacji międzyprocesowej (IPC) między aplikacjami systemu Android. Na przykład jedna aplikacja systemu Android może używać usługi odtwarzacza muzyki pochodzącej z innej aplikacji lub aplikacji może ujawniać dane (takie jak informacje kontaktowe osoby) innym aplikacjom za pośrednictwem usługi.

Usługi i ich zdolność do wykonywania pracy w tle mają kluczowe znaczenie dla zapewnienia bezproblemowego i płynnego interfejsu użytkownika. Wszystkie aplikacje systemu Android mają główny wątek (znany również jako wątek interfejsu użytkownika), na którym są uruchamiane działania. Aby zapewnić szybkość reakcji urządzenia, system Android musi mieć możliwość zaktualizowania interfejsu użytkownika z szybkością 60 klatek na sekundę. Jeśli aplikacja systemu Android wykonuje zbyt wiele pracy na głównym wątku, system Android upuści ramki, co z kolei powoduje, że interfejs użytkownika pojawi się szarpnięci (czasami nazywany również janky). Oznacza to, że każda praca wykonywana na wątku interfejsu użytkownika powinna zostać ukończona w przedziale czasu między dwiema ramkami, około 16 milisekund (1 sekunda co 60 ramek).

Aby rozwiązać ten problem, deweloper może użyć wątków w działaniu, aby wykonać pewną pracę, która zablokowałaby interfejs użytkownika. Może to jednak spowodować problemy. Jest bardzo możliwe, że system Android zniszczy i ponownie utworzy wiele wystąpień działania. Jednak system Android nie zniszczy automatycznie wątków, co może spowodować przecieki pamięci. Najlepszym przykładem jest to, że urządzenie jest obracane — system Android spróbuje zniszczyć wystąpienie działania, a następnie utworzy ponownie nowe:

When device rotates, instance 1 is destroyed and instance 2 is created

Jest to potencjalny wyciek pamięci — wątek utworzony przez pierwsze wystąpienie działania będzie nadal działać. Jeśli wątek zawiera odwołanie do pierwszego wystąpienia działania, uniemożliwi to systemowi Android odzyskiwanie pamięci obiektu. Jednak drugie wystąpienie działania jest nadal tworzone (co z kolei może spowodować utworzenie nowego wątku). Obracanie urządzenia kilka razy w krótkim odstępie czasu może wyczerpać całą pamięć RAM i wymusić zakończenie całej aplikacji w celu odzyskania pamięci.

Jeśli praca do wykonania powinna być wykonywana zgodnie z regułą, należy utworzyć usługę, aby wykonać tę pracę. Jeśli jednak praca ma zastosowanie tylko w kontekście działania, tworzenie wątku do wykonania pracy może być bardziej odpowiednie. Na przykład utworzenie miniatury zdjęcia, które zostało właśnie dodane do aplikacji galerii zdjęć, prawdopodobnie powinno nastąpić w usłudze. Jednak wątek może być bardziej odpowiedni do odtwarzania niektórych muzyki, które powinny być słyszane tylko podczas działania jest na pierwszym planie.

Praca w tle może zostać podzielona na dwie szerokie klasyfikacje:

  1. Długotrwałe zadanie — jest to praca, która trwa do momentu jawnego zatrzymania. Przykładem długotrwałego zadania jest aplikacja, która przesyła strumieniowo muzykę lub musi monitorować dane zebrane z czujnika. Te zadania muszą być uruchamiane, mimo że aplikacja nie ma widocznego interfejsu użytkownika.
  2. Zadania okresowe — (czasami określane jako zadanie) Zadanie okresowe to zadanie stosunkowo krótkie (kilka sekund) i jest uruchamiane zgodnie z harmonogramem (tj. raz dziennie przez tydzień, a może tylko raz w ciągu najbliższych 60 sekund). Przykładem jest pobranie pliku z Internetu lub wygenerowanie miniatury obrazu.

Istnieją cztery różne typy usług systemu Android:

  • Powiązana usługapowiązana usługa to usługa, która ma powiązany z nim inny składnik (zazwyczaj działanie). Powiązana usługa udostępnia interfejs, który umożliwia powiązanemu składnikowi i usłudze interakcję ze sobą. Gdy nie będzie więcej klientów powiązanych z usługą, system Android zamknie usługę.

  • IntentService — Jest IntentService to wyspecjalizowana podklasa Service klasy, która upraszcza tworzenie i używanie usługi. Element IntentService jest przeznaczony do obsługi poszczególnych wywołań autonomicznych. W przeciwieństwie do usługi, która może współbieżnie obsługiwać wiele wywołań, IntentService proces jest bardziej podobny do procesora kolejki pracy — praca jest ustawiana w kolejce i IntentService przetwarza każde zadanie pojedynczo w jednym wątku roboczym. Zazwyczaj elementIntentService nie jest powiązany z działaniem ani fragmentem.

  • Uruchomiona usługausługa uruchomiona to usługa , która została uruchomiona przez inny składnik systemu Android (np. działanie) i jest uruchamiana w tle, dopóki coś jawnie nie nakazuje zatrzymaniu usługi. W przeciwieństwie do powiązanej usługi uruchomiona usługa nie ma żadnych klientów bezpośrednio powiązanych z nią. Z tego powodu ważne jest zaprojektowanie uruchomionych usług, aby mogły zostać bezpiecznie ponownie uruchomione w razie potrzeby.

  • Usługa hybrydowa — usługa hybrydowa to usługa, która ma cechy uruchomionej usługi i powiązanej usługi. Usługę hybrydową można uruchomić, gdy składnik jest z nim powiązany lub może zostać uruchomiony przez pewne zdarzenie. Składnik klienta może lub nie może być powiązany z usługą hybrydową. Usługa hybrydowa będzie działać, dopóki nie zostanie jawnie poinformowana o zatrzymaniu lub dopóki nie będzie więcej klientów powiązanych z nią.

Który typ usługi do użycia jest bardzo zależny od wymagań aplikacji. Jako reguła kciuka usługa IntentService lub powiązana jest wystarczająca dla większości zadań, które musi wykonać aplikacja systemu Android, więc należy przyznać preferencji jednemu z tych dwóch typów usług. Jest IntentService to dobry wybór dla zadań "jednorazowych", takich jak pobieranie pliku, podczas gdy powiązana usługa byłaby odpowiednia, gdy wymagane są częste interakcje z działaniem/fragmentem.

Podczas gdy większość usług działa w tle, istnieje specjalna podkategonia znana jako usługa pierwszego planu. Jest to usługa, która ma wyższy priorytet (w porównaniu z normalną usługą) do wykonywania niektórych zadań dla użytkownika (takich jak odtwarzanie muzyki).

Istnieje również możliwość uruchomienia usługi we własnym procesie na tym samym urządzeniu, jest to czasami nazywane usługą zdalną lub usługą poza procesem. Wymaga to większego nakładu pracy w celu utworzenia, ale może być przydatne, gdy aplikacja musi udostępniać funkcje innym aplikacjom i może w niektórych przypadkach poprawić środowisko użytkownika aplikacji.

Limity wykonywania w tle w systemie Android 8.0

Począwszy od systemu Android 8.0 (poziom interfejsu API 26), aplikacja systemu Android nie ma już możliwości swobodnego uruchamiania w tle. Na pierwszym planie aplikacja może uruchamiać i uruchamiać usługi bez ograniczeń. Gdy aplikacja przejdzie w tle, system Android przyzna aplikacji pewien czas na uruchomienie i korzystanie z usług. Po upływie tego czasu aplikacja nie może już uruchomić żadnych usług, a wszystkie uruchomione usługi zostaną zakończone. W tym momencie aplikacja nie może wykonać żadnej pracy. System Android uważa, że aplikacja ma znajdować się na pierwszym planie, jeśli spełnione są jedno z następujących warunków:

  • Istnieje widoczne działanie (uruchomione lub wstrzymane).
  • Aplikacja uruchomiła usługę pierwszego planu.
  • Inna aplikacja znajduje się na pierwszym planie i używa składników z aplikacji, która byłaby w przeciwnym razie w tle. Przykładem jest to, że jeśli aplikacja A, która znajduje się na pierwszym planie, jest powiązana z usługą dostarczaną przez aplikację B. Aplikacja B będzie również brana pod uwagę na pierwszym planie i nie zostanie zakończona przez system Android w celu bycia w tle.

Istnieją sytuacje, w których mimo że aplikacja znajduje się w tle, system Android obudzi aplikację i zrelaksuje te ograniczenia przez kilka minut, co pozwoli aplikacji wykonać pewną pracę:

  • Aplikacja otrzymuje komunikat o wysokim priorytcie firebase w chmurze.
  • Aplikacja odbiera emisję.
  • Aplikacja odbiera i wykonuje element PendingIntent w odpowiedzi na powiadomienie.

Istniejące aplikacje platformy Xamarin.Android mogą wymagać zmiany sposobu ich działania w tle, aby uniknąć problemów, które mogą wystąpić w systemie Android 8.0. Oto kilka praktycznych alternatyw dla usługi systemu Android:

  • Planowanie pracy w tle przy użyciu harmonogramu zadań systemu Android lub narzędzia Firebase Job Dispatcher — te dwie biblioteki zapewniają platformę dla aplikacji do segregowania pracy w tle w zadaniach, dyskretnej jednostki pracy. Aplikacje mogą następnie zaplanować zadanie z systemem operacyjnym wraz z pewnymi kryteriami dotyczącymi tego, kiedy zadanie może zostać uruchomione.
  • Uruchom usługę na pierwszym planie — usługa pierwszego planu jest przydatna, gdy aplikacja musi wykonać pewne zadanie w tle, a użytkownik może potrzebować okresowej interakcji z tym zadaniem. Usługa pierwszego planu wyświetli trwałe powiadomienie, aby użytkownik wiedział, że aplikacja uruchamia zadanie w tle, a także umożliwia monitorowanie lub interakcję z zadaniem. Przykładem może być aplikacja podcastingowa, która odtwarza podcast dla użytkownika lub może pobrać odcinek podcastu, aby móc cieszyć się później.
  • Użyj komunikatu o wysokim priorytcie Firebase Cloud Message (FCM) — gdy system Android otrzyma usługę FCM o wysokim priorytcie dla aplikacji, umożliwi uruchamianie usług w tle przez krótki czas. Byłoby to dobrą alternatywą dla usługi w tle, która sonduje aplikację w tle.
  • Odroczenie pracy w przypadku, gdy aplikacja wchodzi na pierwszy plan — jeśli żadne z poprzednich rozwiązań nie jest możliwe, aplikacje muszą opracowywać własny sposób wstrzymywania i wznawiania pracy po przejściu aplikacji na pierwszy plan.