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.