Android: AsyncTask vs Service

138

Dlaczego w odpowiedziach na większość pytań czytam dużo o AsyncTaskładowarkach, ale nic o usługach ? Czy usługi po prostu nie są dobrze znane, czy są przestarzałe, mają jakieś złe atrybuty lub coś takiego? Jakie są różnice?

(Nawiasem mówiąc, wiem, że są na ten temat inne wątki, ale tak naprawdę żaden z nich nie wskazuje wyraźnych różnic, które pomagają deweloperowi łatwo zdecydować, czy lepiej będzie wykorzystać jeden lub drugi do rzeczywistego problemu.)

erikbwork
źródło

Odpowiedzi:

272

W niektórych przypadkach można wykonać to samo zadanie za pomocą jednego AsyncTasklub Servicedrugiego, jednak zwykle jedno jest lepiej dostosowane do zadania niż drugie.

AsyncTasks są przeznaczone do jednorazowych, czasochłonnych zadań, których nie można uruchomić w wątku interfejsu użytkownika. Typowym przykładem jest pobieranie / przetwarzanie danych po naciśnięciu przycisku.

Services są zaprojektowane do ciągłego działania w tle. W powyższym przykładzie pobierania danych po naciśnięciu przycisku można uruchomić usługę, pozwolić jej pobrać dane, a następnie ją zatrzymać, ale jest to nieefektywne. O wiele szybciej jest użyć narzędzia AsyncTask, które uruchomi się raz, zwróci dane i gotowe.

Jeśli jednak musisz ciągle robić coś w tle, Servicenajlepszym rozwiązaniem jest. Przykłady obejmują odtwarzanie muzyki, ciągłe sprawdzanie nowych danych itp.

Ponadto, jak już powiedział Sherif, usługi niekoniecznie są uruchamiane z wątku interfejsu użytkownika.

W większości przypadków Servicesą one przeznaczone do uruchamiania kodu, nawet jeśli aplikacja Activitynie jest otwarta. AsyncTasks są zaprojektowane tak, aby wykonywanie kodu poza wątkiem interfejsu użytkownika było niezwykle proste.

Komputerowe
źródło
2
Ciekawe, że w tym wystąpieniu z Google I / O w 2010 roku youtube.com/watch?v=xHXn3Kg2IQE prezenter podaje 3 różne metody pobierania danych z REST API, a pierwszy z nich korzysta z usługi. Nie jestem ekspertem od Androida, ale miałem też wrażenie, że to, co powiedział Computerish, jest w zasadzie poprawne.
wuliwong
10
Ostatni akapit: „Usługi służą do uruchamiania kodu, nawet jeśli Aktywność aplikacji nie jest otwarta”. Dotyczy to również wątków AsyncTask lub w tle. tj. gdy wciśniesz swoją aktywność lub wywołasz finish (), a Twoja aktywność nie jest widoczna, ale nadal Twoje wątki w tle są wykonywane do momentu zakończenia procesu aplikacji (np. poprzez zamianę z ostatnich zadań). Sprawdziłem to z 4.4.2 Google Nexus AOSP grouper
Shirish Herwade
10
Jednak AsyncTask może być trudny, jeśli działanie, które go uruchomiło, zostanie zabite, gdy AsyncTask nadal działa i musi zaktualizować interfejs użytkownika po jego zakończeniu ... (co nie zadziała, ponieważ działanie zostało już zniszczone). Dlaczego nie skorzystać z usługi IntentService, której nie trzeba przerywać ręcznie, ponieważ kończy się ona po zakończeniu?
AgentKnopf
świetne punkty. dobre wyjaśnienie na temat usługi. oznacza to, że usługa działa w tle nieprzerwanie, nawet gdy praca jest wykonana.
BABU K
3
@LarsH Popraw mnie, jeśli się mylę, ale myślę, że możesz użyć BroadcastReceiver w swojej aktywności / fragmencie, a z usługi IntentService po prostu uruchom Broadcast, gdy skończysz. Ponieważ możesz ponownie zarejestrować się do transmisji po odtworzeniu aktywności / fragmentu, co powinno Cię obejmować. Inną alternatywą byłoby użycie EventBus do aktualizacji interfejsu użytkownika (chociaż staram się ich unikać - utrudnia śledzenie kodu imo).
AgentKnopf
58

Usługi są zupełnie inne: Usługi to nie wątki !

Twoje działanie wiąże się z usługą, a usługa zawiera pewne funkcje, które po wywołaniu blokują wątek wywołujący. Twoja usługa może służyć do zmiany temperatury z Celsjusza na stopnie. Dowolna powiązana aktywność może uzyskać tę usługę.


Jednak AsyncTaskjest to wątek, który wykonuje pewną pracę w tle i jednocześnie ma możliwość raportowania wyników z powrotem do wątku wywołującego.

Tylko myśl: usługa może mieć AsyncTaskprzedmiot!

Sherif elKhatib
źródło
2
Usługi są opisane jako działające w tle, działające nawet po zamknięciu aplikacji. AsyncTask jest również używany do robienia czegoś w tle. Wiesz co mam na myśli?
erikbwork
1
tak, ale usługi mogą coś robić lub nie. To długotrwały OBIEKT
Sherif elKhatib
„Usługa może mieć obiekt AsyncTask!” Dzięki za zwrócenie uwagi. Ale czy to dobry pomysł - czy to jest coś, co byś polecił? A może lepiej byłoby użyć bardziej podstawowych technik wątkowania w usłudze?
RenniePet
„Twoja aktywność jest powiązana z usługą” niekoniecznie.
JacksOnF1re
@ JacksOnF1re Wiem, że to tak, jak wtedy, gdy po raz pierwszy zacząłem kodować: p, ale „Twoja aktywność wiąże się z usługą” to prawdziwe stwierdzenie. Mógłbym również być związany z tą usługą. Lodówka też może się przydać. Nie oznacza to, że oświadczenie jest nieważne. W każdym razie jk
Sherif elKhatib
7

Servicejest jednym z elementów frameworka Androida, który nie wymaga UI do wykonania, co oznacza, że ​​nawet gdy aplikacja nie jest aktywnie używana przez użytkownika, możesz wykonać jakąś operację z usługą. Nie oznacza to, że usługa będzie działać w osobnym wątku, ale działa w wątku głównym i operację można w razie potrzeby wykonać w osobnym wątku. Przykłady zastosowań to odtwarzanie muzyki w tle, synchronizowanie danych z serwerem w tle bez interakcji użytkownika itp

AsyncTaskz drugiej strony jest używany do zadań blokowania interfejsu użytkownika, które mają być wykonywane w osobnym wątku. To tak samo, jak tworzenie nowego wątku i wykonywanie zadania, gdy wszystkie zadania związane z tworzeniem i utrzymywaniem wątków oraz wysyłaniem wyników do głównego wątku są obsługiwane przez AsyncTask Przykład użycia to pobieranie danych z serwera, operacje CRUD na resolwerze treści itp.

arjun
źródło
Czy możesz określić, dlaczego uważasz, że Twoja odpowiedź coś dodaje do pytania?
erikbwork
2
inne odpowiedzi są albo za krótkie, albo za długie, by początkujący mogli je zrozumieć. więc odpowiedziałem dokładnie prostymi słowami z przykładami
arjun
6

Service i asynctasks robią prawie to samo, prawie .using service lub asynctask zależy od twoich wymagań.

na przykład, jeśli chcesz załadować dane do widoku listy z serwera po naciśnięciu jakiegoś przycisku lub zmianie ekranu, lepiej idź z asynctask.it działa równolegle z głównym wątkiem interfejsu użytkownika (działa w tle). do uruchomienia aktywności asynctack lub twoja aplikacja powinna w głównym wątku interfejsu użytkownika. po wyjściu z aplikacji nie ma asynctask.

Ale usługi nie są takie, po uruchomieniu usługi może ona działać po wyjściu z aplikacji, chyba że zatrzymasz usługę. Tak jak powiedziałem, zależy to od twoich wymagań. Jeśli chcesz nadal sprawdzać odbieranie danych lub sprawdzać stan sieci ciągle lepiej idź z obsługą.

szczęśliwego kodowania.

Ashana.Jackol
źródło
1
Cześć Ashana, czy mogę zapytać, dlaczego podałeś tę odpowiedź na pytanie, na które już udzielono odpowiedzi? Czy nie jesteś zadowolony z istniejącej zaznaczonej odpowiedzi? A może próbujesz zbudować profil SO, pisząc swoją opinię na wszystkie pytania, o których masz coś do powiedzenia? A może coś zupełnie innego? Nie mogę tego rozgryźć, ale ostatnio często widzę ten wzór.
erikbwork
3
tak, wiem, że odpowiedź jest już udzielona i nie widzę tutaj większego problemu, jeśli podam właściwą odpowiedź lub moją opinię tutaj, bracie? ponieważ nie jesteś jedyną osobą, która szuka odpowiedzi na to samo pytanie, jeśli ktoś trudny do zrozumienia rozwiązania w powyższych odpowiedziach może przewinąć w dół do szukania odpowiedzi, która będzie dla niego odpowiednia, łatwo ją zrozumie. Dzięki za komentarz stary, nie
jestem
1

W kilku przypadkach możesz osiągnąć tę samą funkcjonalność, używając obu. W przeciwieństwie do zadania asynchronicznego usługa ma własny cykl życia i dziedziczy kontekst (usługa jest bardziej niezawodna niż zadanie asynchroniczne). Usługa może działać nawet po zamknięciu aplikacji. Jeśli chcesz coś zrobić nawet po zamknięciu aplikacji, a także potrzebujesz zmiennej kontekstowej, przejdziesz do usługi.

Przykład: Jeśli chcesz odtwarzać muzykę i nie chcesz wstrzymywać, jeśli użytkownik opuści aplikację, na pewno wybierzesz usługę.

sayem siam
źródło
1

Porównanie lokalnej usługi klasy bazowej w toku z AsyncTask:

✱ (Ta odpowiedź nie dotyczy usług eksportowanych ani żadnej usługi działającej w procesie innym niż proces klienta, ponieważ oczekiwane przypadki użycia różnią się znacznie od przypadków użycia AsyncTask. Ponadto, w interesie zwięzłości, charakter pewnych wyspecjalizowanych Servicepodklasy (np IntentService, JobService) będą ignorowane tutaj).

Żywotność procesu

A Servicereprezentuje dla systemu operacyjnego „chęć aplikacji do wykonywania dłuższej operacji bez interakcji z użytkownikiem” [ ref ].

Kiedy masz Serviceuruchomiony, Android rozumie, że nie chcesz, aby Twój proces został zabity. Dotyczy to również sytuacji, gdy masz Activityekran, a jest to szczególnie prawdziwe, gdy używasz usługi pierwszego planu . (Kiedy wszystkie składniki aplikacji znikną, system Android myśli: „Och, teraz jest dobry czas, aby zabić tę aplikację, abym mógł zwolnić zasoby”).

Ponadto, w zależności od ostatniej zwróconej wartości z Service.onCreate(), Android może próbować „ożywić” aplikacje / usługi, które zostały zabite z powodu presji zasobów [ ref ].

AsyncTasksnie rób tego. Nie ma znaczenia, ile wątków w tle masz uruchomionych ani jak ciężko pracują: Android nie utrzyma twojej aplikacji przy życiu tylko dlatego, że aplikacja korzysta z procesora. Musi mieć jakiś sposób, aby wiedzieć, że Twoja aplikacja nadal ma pracę; dlatego Servicessą zarejestrowane w systemie operacyjnym, a AsyncTasksnie.

Wielowątkowość

AsyncTasks polegają na utworzeniu wątku w tle, na którym można wykonać pracę, a następnie zaprezentowaniu wyniku tej pracy wątkowi interfejsu użytkownika w sposób bezpieczny dla wątków.

Każde nowe AsyncTaskwykonanie generalnie skutkuje większą współbieżnością (większą liczbą wątków), z zastrzeżeniem ograniczeń AsyncTasks'spuli wątków [ ref ].

ServiceZ drugiej strony metody są zawsze wywoływane w wątku interfejsu użytkownika [ ref ]. Odnosi się to do onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), itd. Tak więc, w pewnym sensie, Servicesnie zrobić „run” w tle. Po uruchomieniu ( onCreate()) po prostu „siedzą” tam - aż nadejdzie czas na wyczyszczenie, wykonanie onStartCommand()itp.

Innymi słowy, dodanie kolejnych Servicesnie powoduje większej współbieżności. Metody serwisowe nie są dobrym miejscem do wykonywania dużej ilości pracy, ponieważ działają w wątku interfejsu użytkownika .

Oczywiście możesz je rozszerzać Service, dodawać własne metody i wywoływać je z dowolnego wątku. Ale jeśli to zrobisz, odpowiedzialność za bezpieczeństwo nici spoczywa na tobie - a nie na strukturze.

Jeśli chcesz dodać wątek w tle (lub innego rodzaju pracownika) do swojego Service, możesz to zrobić. Możesz na przykład rozpocząć wątek / AsyncTaskin w tle Service.onCreate(). Ale nie wszystkie przypadki użycia tego wymagają. Na przykład:

  • Możesz chcieć nadal Servicedziałać, aby nadal otrzymywać aktualizacje lokalizacji w „tle” (co oznacza, że ​​niekoniecznie musisz Activitieswyświetlać na ekranie).
  • Możesz też chcieć utrzymać swoją aplikację przy życiu tylko po to, aby móc BroadcastReceiverprzez dłuższy czas rejestrować „niejawną” (po API 26 nie zawsze możesz to zrobić za pomocą manifestu, więc zamiast tego musisz zarejestrować się w czasie wykonywania [ ref ]).

Żaden z tych przypadków użycia nie wymaga dużej aktywności procesora; wymagają tylko, aby aplikacja nie została zabita .

Jako pracownicy

Servicesnie są zorientowane na zadania. Nie są skonfigurowane do „wykonywania zadania” i „dostarczania wyniku”, jak AsyncTaskssą. Servicesnie rozwiązują żadnych problemów związanych z bezpieczeństwem wątków (niezależnie od faktu, że wszystkie metody są wykonywane w jednym wątku). AsyncTasksz drugiej strony zajmij się tą złożonością za siebie.

Zauważ, że AsyncTaskjest to przestarzałe . Ale to nie oznacza, że należy wymienić AsyncTasksz Services! (Jeśli dowiedziałeś się czegoś z tej odpowiedzi, to powinno być jasne).

TL; DR

Servicessą głównie po to, by „istnieć”. Działają jak poza ekranem Activity, dając powód, dla którego aplikacja pozostaje żywa, podczas gdy inne komponenty zajmują się „pracą”. AsyncTaskswykonują „pracę”, ale same w sobie nie utrzymają procesu przy życiu.

greeble31
źródło