Android: AsyncTask vs Service


138

Perché leggo molto spesso la risposta alla maggior parte delle domande su AsyncTaske Caricatori ma nulla sui Servizi ? I servizi non sono conosciuti molto bene o sono deprecati o hanno attributi negativi o qualcosa del genere? Quali sono le differenze?

(A proposito, so che ci sono altri thread a riguardo, ma nessuno afferma davvero chiare differenze che aiutano uno sviluppatore a decidere facilmente se sta meglio usando l'uno o l'altro per un problema reale.)

Risposte:


272

In alcuni casi è possibile eseguire lo stesso compito con uno AsyncTasko uno, Servicema di solito uno è più adatto a un compito rispetto all'altro.

AsyncTasksono progettati per attività che richiedono una tantum e che non possono essere eseguite sul thread dell'interfaccia utente. Un esempio comune è il recupero / elaborazione dei dati quando si preme un pulsante.

Servicesono progettati per funzionare continuamente in background. Nell'esempio sopra di recupero dei dati quando si preme un pulsante, è possibile avviare un servizio, lasciarlo recuperare i dati e quindi interromperlo, ma questo è inefficiente. È molto più veloce usare un programma AsyncTaskche verrà eseguito una volta, restituirà i dati e sarà fatto.

Se devi fare continuamente qualcosa in background, tuttavia, Serviceè la soluzione migliore. Esempi di questo includono la riproduzione di musica, il controllo continuo di nuovi dati, ecc.

Inoltre, come già detto da Sherif, i servizi non scappano necessariamente dal thread dell'interfaccia utente.

Per la maggior parte, Services è per quando si desidera eseguire il codice anche quando l'applicazione Activitynon è aperta. AsyncTasks sono progettati per rendere incredibilmente semplice l'esecuzione del codice al di fuori del thread dell'interfaccia utente.


2
È interessante notare che in questo discorso di Google I / O del 2010 su youtube.com/watch?v=xHXn3Kg2IQE il presentatore offre 3 metodi diversi per ottenere dati da un'API REST e il primo utilizza un servizio. Non sono un esperto di Android, ma avevo anche l'impressione che ciò che Computerish dicesse fosse sostanzialmente corretto.
wuliwong,

10
L'ultimo paragrafo, "I servizi sono per quando si desidera eseguire il codice anche quando l'attività dell'applicazione non è aperta". Questo è anche il caso di AsyncTask o thread in background. vale a dire quando torni indietro nella tua attività o chiami finish () e la tua attività non è visibile, ma i tuoi thread in background vengono eseguiti fino a quando non interrompi il processo dell'app (ad esempio scambiando da attività recenti). Ho verificato questo con 4.4.2 Cernia Google Nexus AOSP
Shirish Herwade,

10
Tuttavia, AsyncTask può essere complicato se l'attività che l'ha avviata viene interrotta mentre AsyncTask è ancora in esecuzione e deve aggiornare l'interfaccia utente una volta terminata ... (che non funzionerà poiché l'attività è già distrutta). Perché non usare un IntentService che non è necessario interrompere manualmente, poiché termina semplicemente una volta fatto?
AgentKnopf,

ottimi punti. buona spiegazione del servizio. Questo è il servizio in esecuzione in background continuamente anche il lavoro è fatto.
BABU K,

3
@LarsH Correggimi se sbaglio, ma penso che potresti usare un BroadcastReceiver nella tua attività / frammento e da IntentService semplicemente lanci un broadcast una volta finito. Dal momento che è possibile ri-registrarsi per le trasmissioni al momento della ricostruzione di Attività / Frammento che dovrebbe essere coperta. Un'altra alternativa sarebbe usare un EventBus per aggiornare l'interfaccia utente (anche se provo a evitarli - rende il codice più difficile da seguire imo).
AgentKnopf,

58

I servizi sono completamente diversi: i servizi non sono discussioni !

La tua attività si lega a un servizio e il servizio contiene alcune funzioni che quando vengono chiamate, bloccano il thread chiamante. Il servizio potrebbe essere utilizzato per modificare la temperatura da Celsius a Gradi. Qualsiasi attività vincolante può ottenere questo servizio.


Tuttavia AsyncTaskè un thread che fa un po 'di lavoro in background e allo stesso tempo ha la possibilità di riportare i risultati al thread chiamante.

Solo un pensiero: un servizio può avere un AsyncTaskoggetto!


2
I servizi sono descritti come in esecuzione in background, continuando anche quando la tua applicazione è chiusa. AsyncTask è anche usato per fare qualcosa in background. Sai cosa intendo?
erikbwork,

1
sì, ma i servizi potrebbero o meno fare qualcosa. Sono un OGGETTO di lunga durata
Sherif elKhatib,

"Un servizio può avere un oggetto AsyncTask!" Grazie per la segnalazione. Ma è una buona idea - è qualcosa che consiglieresti? O sarebbe meglio usare tecniche di threading più basilari in un servizio?
RenniePet,

"La tua attività si lega a un servizio" non necessariamente.
JacksOnF1re

@ JacksOnF1re So che è come quando ho iniziato a scrivere codice: p ma "La tua attività si lega a un servizio" è una vera affermazione. Potrei anche essere vincolante per questo servizio. Anche un frigorifero potrebbe essere vincolante. Questo non rende la dichiarazione non valida .. comunque jk
Sherif elKhatib

7

Serviceè uno dei componenti del framework Android, che non richiede l'esecuzione dell'interfaccia utente, il che significa che anche quando l'app non viene utilizzata attivamente dall'utente, è possibile eseguire alcune operazioni con il servizio. Ciò non significa che il servizio verrà eseguito in un thread separato, ma verrà eseguito nel thread principale e l'operazione potrà essere eseguita in un thread separato quando necessario. Esempi di utilizzo sono la riproduzione di musica in background, la sincronizzazione dei dati con il server in backgroud senza l'interazione dell'utente, ecc

AsyncTaskd'altra parte viene utilizzato per le attività di blocco dell'interfaccia utente da eseguire su un thread separato. È come creare un nuovo thread e svolgere l'attività quando tutte le attività di creazione e manutenzione dei thread e di invio del risultato al thread principale sono curate da AsyncTask. Esempio di utilizzo sono il recupero di dati dal server, operazioni CRUD sul risolutore di contenuti, ecc.


puoi specificare perché pensi che la tua risposta aggiunga qualcosa alla domanda?
erikbwork,

2
altre risposte sono troppo brevi o troppo lunghe per essere capite dai principianti. così ho risposto precisamente con parole semplici con esempi
arjun

6

Service e asynctask stanno quasi facendo la stessa cosa, quasi utilizzando un servizio o un asincrono dipende da quale sia il tuo requisito.

ad esempio se vuoi caricare i dati in una visualizzazione elenco da un server dopo aver premuto un pulsante o aver cambiato schermata, è meglio andare con un asynctask.it funziona parallelamente al thread principale dell'interfaccia utente (viene eseguito in background). per eseguire attività asincrono o la tua app dovrebbe sull'interfaccia utente principale thread.after uscita dall'app non c'è asynctask.

Ma i servizi non sono così, una volta avviato un servizio può essere eseguito dopo essere uscito dall'app, a meno che non si interrompa il servizio. Come ho detto, dipende dal tuo requisito. continuamente è meglio andare con il servizio.

buona programmazione.


1
Ciao Ashana, posso chiederti perché hai fornito questa risposta a una domanda a cui è già stata data una risposta? Non sei soddisfatto della risposta contrassegnata esistente? Oppure provi a creare un profilo SO scrivendo la tua opinione su tutte le domande di cui hai qualcosa da dire? O qualcosa di completamente diverso? Non riesco a capirlo, ma ultimamente vedo quello schema abbastanza spesso.
erikbwork,

3
sai che la risposta è già stata data e non vedo molti problemi qui se do la risposta giusta o la mia opinione qui fratello? perché non sei l'unico a cercare la risposta alla stessa domanda, se qualcuno riesce a capire la soluzione nelle risposte sopra, può scorrere verso il basso per cercare una risposta adatta a loro, capirne facilmente una. Grazie per il commento fratello, non sono un genio o un professionista nella programmazione, voglio solo aiutare gli altri, provare ad insegnare agli altri quello che già conosco :)
Ashana.Jackol

1

In alcuni casi, è possibile ottenere la stessa funzionalità utilizzando entrambi. Diversamente dall'attività asincrona, il servizio ha il proprio ciclo di vita ed eredita il contesto (il servizio è più robusto di un'attività asincrona). Il servizio può essere eseguito anche se si è usciti dall'app. Se vuoi fare qualcosa anche dopo la chiusura dell'app e hai anche bisogno della variabile di contesto, scegli Service.

Esempio: se si desidera riprodurre una musica e non si desidera mettere in pausa se l'utente lascia l'app, si andrà sicuramente al servizio.


1

Confronto di un servizio locale, in-process, di classe base ✱ con un AsyncTask:

✱ (Questa risposta non riguarda i servizi esportati o qualsiasi servizio che viene eseguito in un processo diverso da quello del cliente, poiché i casi d'uso previsti differiscono sostanzialmente da quelli di un AsyncTask. Inoltre, nell'interesse della brevità, la natura di alcuni specialisti Servicesottoclassi (ad esempio, IntentService, JobService) verranno ignorati qui.)

Durata del processo

A Servicerappresenta, per il sistema operativo, "il desiderio di un'applicazione di eseguire un'operazione più lunga senza interagire con l'utente" [ ref ].

Mentre hai una Servicecorsa, Android capisce che non vuoi che il tuo processo venga ucciso. Questo vale anche ogni volta che si dispone di uno Activityschermo ed è particolarmente vero quando si esegue un servizio in primo piano . (Quando tutti i componenti dell'applicazione scompaiono , Android pensa "Oh, ora è un buon momento per uccidere questa app, così posso liberare risorse".)

Inoltre, a seconda dell'ultimo valore restituito da Service.onCreate(), Android può tentare di "ripristinare" app / servizi che sono stati uccisi a causa della pressione delle risorse [ ref ].

AsyncTasksnon fare nulla di tutto ciò. Non importa quanti thread in background hai in esecuzione o quanto duramente stiano funzionando: Android non manterrà la tua app in vita solo perché la tua app utilizza la CPU. Deve avere un modo per sapere che la tua app ha ancora del lavoro da fare; ecco perché Servicessono registrati con il sistema operativo e AsyncTasksnon lo sono.

multithreading

AsyncTasks si tratta solo di creare un thread in background su cui lavorare, e quindi di presentare il risultato di tale lavoro al thread dell'interfaccia utente in modo thread-safe.

Ogni nuova AsyncTaskesecuzione comporta generalmente una maggiore concorrenza (più thread), soggetti alle limitazioni del AsyncTasks'spool di thread [ ref ].

Servicei metodi, d'altra parte, sono sempre invocati sul thread dell'interfaccia utente [ ref ]. Questo vale per onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), ecc Quindi, in un certo senso, Servicesnon "gira" in background. Una volta avviato ( onCreate()), si limitano a "sedersi" lì - fino a quando non è il momento di ripulire, eseguire un onStartCommand(), ecc.

In altre parole, l'aggiunta di ulteriori Servicesnon comporta una maggiore concorrenza. I metodi di servizio non sono un buon posto per fare grandi quantità di lavoro, perché vengono eseguiti sul thread dell'interfaccia utente .

Naturalmente, puoi estendere Service, aggiungere i tuoi metodi e chiamarli da qualsiasi thread desideri. Ma se lo fai, la responsabilità della sicurezza del thread spetta a te, non alla struttura.

Se vuoi aggiungere un thread in background (o qualche altro tipo di lavoratore) al tuo Service, sei libero di farlo. Ad esempio, è possibile avviare un thread / AsyncTaskin background Service.onCreate(). Ma non tutti i casi d'uso lo richiedono. Per esempio:

  • Potresti voler continuare a Servicecorrere in modo da poter continuare a ricevere aggiornamenti sulla posizione in "background" (ovvero, senza necessariamente avere Activitiessullo schermo).
  • Oppure, potresti voler mantenere in vita la tua app solo per poter tenere un "implicito" BroadcastReceiverregistrato a lungo termine (dopo l'API 26, non puoi sempre farlo tramite manifest, quindi devi invece registrarti in fase di esecuzione [ ref ]).

Nessuno di questi casi d'uso richiede molta attività della CPU; richiedono solo che l'app non venga uccisa .

Come lavoratori

Servicesnon sono orientati alle attività. Non sono impostati per "eseguire un'attività" e "consegnare un risultato", come lo AsyncTaskssono. Servicesnon risolve alcun problema di sicurezza dei thread (nonostante il fatto che tutti i metodi vengano eseguiti su un singolo thread). AsyncTasksd'altra parte, gestisci quella complessità per te.

Si noti che AsyncTaskè previsto per la deprecazione . Ma ciò non significa che dovresti sostituirlo AsyncTaskscon Services! (Se hai imparato qualcosa da questa risposta, questo dovrebbe essere chiaro.)

TL; DR

Servicessono principalmente lì per "esistere". Sono come uno schermo spento Activity, fornendo una ragione per cui l'app rimane in vita, mentre altri componenti si occupano di fare il "lavoro". AsyncTasksfanno "lavoro", ma non mantengono vivo un processo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.