Android: AsyncTask vs Service

138

Pourquoi est-ce que je lis beaucoup dans la réponse à la plupart des questions sur les AsyncTaskchargeurs et rien sur les services ? Les services ne sont-ils tout simplement pas très bien connus ou sont-ils obsolètes ou ont de mauvais attributs ou quelque chose du genre? Quelles sont les différences?

(En passant, je sais qu'il existe d'autres sujets à ce sujet, mais aucun n'indique vraiment de différences claires qui aident un développeur à décider facilement s'il vaut mieux utiliser l'un ou l'autre pour un problème réel.)

erikbwork
la source

Réponses:

272

Dans certains cas, il est possible d'accomplir la même tâche avec un AsyncTaskou un Servicemais généralement l'un est mieux adapté à une tâche que l'autre.

AsyncTaskLes s sont conçus pour des tâches chronophages qui ne peuvent pas être exécutées par le thread d'interface utilisateur. Un exemple courant est la récupération / le traitement de données lorsqu'un bouton est enfoncé.

ServiceLes s sont conçus pour fonctionner en permanence en arrière-plan. Dans l'exemple ci-dessus de récupération de données lorsqu'un bouton est enfoncé, vous pouvez démarrer un service, le laisser récupérer les données, puis l'arrêter, mais cela est inefficace. Il est beaucoup plus rapide d'utiliser un AsyncTaskqui s'exécutera une fois, retournera les données et sera terminé.

Si vous avez besoin de faire continuellement quelque chose en arrière-plan, Servicec'est votre meilleur choix. Des exemples de cela incluent la lecture de musique, la vérification continue de nouvelles données, etc.

De plus, comme Sherif l'a déjà dit, les services ne fonctionnent pas nécessairement à partir du thread de l'interface utilisateur.

Pour la plupart, les Services sont utilisés lorsque vous souhaitez exécuter du code même lorsque votre application Activityn'est pas ouverte. AsyncTaskLes s sont conçus pour rendre l'exécution de code hors du thread d'interface utilisateur incroyablement simple.

Informatisé
la source
2
Il est intéressant de noter que dans cette conférence de Google I / O en 2010 youtube.com/watch?v=xHXn3Kg2IQE, le présentateur donne 3 méthodes différentes pour obtenir des données à partir d'une API REST et la première utilise un service. Je ne suis pas un expert Android, mais j'avais également l'impression que ce que Computerish a dit est fondamentalement correct.
wuliwong
10
Le dernier paragraphe, "Les services sont destinés lorsque vous souhaitez exécuter du code même lorsque l'activité de votre application n'est pas ouverte". C'est également le cas avec AsyncTask ou les threads d'arrière-plan. c'est-à-dire lorsque vous appuyez de nouveau sur votre activité ou que vous appelez finish () et que votre activité n'est pas visible, mais que vos threads d'arrière-plan s'exécutent jusqu'à ce que vous tuiez le processus de votre application (par exemple en échangeant des tâches récentes). J'ai vérifié cela avec 4.4.2
Mérou
10
Cependant, AsyncTask peut être délicat si l'activité qui l'a démarrée est tuée alors que l'AsyncTask est toujours en cours d'exécution et doit mettre à jour l'interface utilisateur une fois qu'elle est terminée ... (ce qui ne fonctionnera pas car l'activité est déjà détruite). Pourquoi ne pas utiliser un IntentService que vous n'avez pas besoin d'arrêter manuellement, car il se termine simplement une fois terminé?
AgentKnopf
excellents points.bonne explication sur le service.C'est un service fonctionnant en arrière-plan en continu, même le travail est fait.
BABU K le
3
@LarsH Corrigez-moi si je me trompe, mais je pense que vous pouvez utiliser un BroadcastReceiver dans votre activité / fragment et depuis le service Intent, vous déclenchez simplement une diffusion une fois que vous avez terminé. Étant donné que vous pouvez vous réinscrire aux diffusions lors de la recréation d'activité / fragment, cela devrait vous couvrir. Une autre alternative serait d'utiliser un EventBus pour mettre à jour l'interface utilisateur (bien que j'essaie d'éviter ceux-ci - rend le code plus difficile à suivre imo).
AgentKnopf
58

Les services sont complètement différents: les services ne sont pas des threads !

Votre activité se lie à un service et le service contient certaines fonctions qui, lorsqu'elles sont appelées, bloquent le thread appelant. Votre service peut être utilisé pour changer la température de Celsius à Degrés. Toute activité qui se lie peut obtenir ce service.


Cependant, il AsyncTasks'agit d'un thread qui effectue un certain travail en arrière-plan et qui a en même temps la possibilité de rapporter les résultats au thread appelant.

Juste une pensée: un service peut avoir un AsyncTaskobjet!

Sherif elKhatib
la source
2
Les services sont décrits comme s'exécutant en arrière-plan, continuant même lorsque votre application est fermée. AsyncTask est également utilisé pour faire quelque chose en arrière-plan. Sais ce que je veux dire?
erikbwork
1
ouais, mais les services peuvent ou non faire quelque chose. Ils sont un OBJET de longue durée
Sherif elKhatib
"Un service peut avoir un objet AsyncTask!" Merci d'avoir fait remarquer cela. Mais est-ce une bonne idée - est-ce quelque chose que vous recommanderiez? Ou serait-il préférable d'utiliser des techniques de threading plus basiques dans un service?
RenniePet
"Votre activité est liée à un service" pas nécessairement.
JacksOnF1re
@ JacksOnF1re Je sais que c'est comme quand j'ai commencé à coder: p mais "Votre activité se lie à un service" est une vraie déclaration. Je pourrais également être lié à ce service. Un réfrigérateur peut également être contraignant. Cela ne rend pas la déclaration invalide .. de toute façon jk
Sherif elKhatib
7

Serviceest l'un des composants du framework Android, qui ne nécessite pas d'interface utilisateur pour s'exécuter, ce qui signifie que même lorsque l'application n'est pas activement utilisée par l'utilisateur, vous pouvez effectuer une opération avec le service. Cela ne signifie pas que le service s'exécutera dans un thread séparé, mais qu'il s'exécutera dans le thread principal et que l'opération peut être effectuée dans un thread séparé si nécessaire. Les exemples d'utilisations sont la lecture de musique en arrière-plan, la synchronisation des données avec le serveur en arrière-plan sans interaction de l'utilisateur, etc.

AsyncTaskd'autre part, est utilisé pour les tâches de blocage de l'interface utilisateur à effectuer sur un thread séparé. C'est la même chose que la création d'un nouveau thread et l'exécution de la tâche lorsque toutes les tâches de création et de maintenance des threads et de renvoi du résultat au thread principal sont prises en charge par l'utilisation d'AsyncTask.

Arjun
la source
pouvez-vous préciser pourquoi vous pensez que votre réponse ajoute quelque chose à la question?
erikbwork
2
les autres réponses sont soit trop courtes, soit trop longues à comprendre pour les débutants. alors j'ai répondu précisément avec des mots simples avec des exemples
arjun
6

Service et asynctasks font presque la même chose, presque un service ou d' un AsyncTask .En utilisant dépend de ce qui est votre exigence.

par exemple, si vous souhaitez charger des données dans une vue de liste à partir d'un serveur après avoir appuyé sur un bouton ou changé d'écran, vous feriez mieux d'utiliser un asynctask.il fonctionne en parallèle avec le thread d'interface utilisateur principal (s'exécute en arrière-plan) .pour exécuter l'activité asynctack ou votre application devrait sur le thread principal de l'interface utilisateur, après la sortie de l'application, il n'y a pas d'asynctask.

Mais les services ne sont pas comme ça, une fois que vous démarrez un service, il peut fonctionner après avoir quitté l'application, sauf si vous arrêtez le service.Comme je l'ai dit, cela dépend de vos besoins.Si vous souhaitez continuer à vérifier la réception des données ou vérifier l'état du réseau vous feriez mieux de continuer avec le service.

bon codage.

Ashana.Jackol
la source
1
Salut Ashana, puis-je vous demander pourquoi vous avez fourni cette réponse à une question à laquelle on a déjà répondu? Êtes-vous mécontent de la réponse marquée existante? Ou essayez-vous de créer un profil SO en écrivant votre opinion sur toutes les questions sur lesquelles vous avez quelque chose à dire? Ou quelque chose de complètement différent? Je ne peux pas le comprendre, mais je vois ce modèle assez souvent ces derniers temps.
erikbwork
3
ya je sais que la réponse est déjà donnée et je ne vois pas beaucoup de problème ici si je donne la bonne réponse ou mon opinion ici bro? parce que vous n'êtes pas le seul à chercher la réponse à la même question, si quelqu'un a du mal à comprendre la solution dans les réponses ci-dessus, il / elle peut faire défiler vers le bas pour chercher une réponse qui lui convient, comprendre facilement une. Merci pour le commentaire frère, je ne suis pas un génie ou un pro de la programmation, je veux juste aider les autres, essayez d'enseigner aux autres ce que je sais déjà :)
Ashana.Jackol
1

Dans de rares cas, vous pouvez obtenir la même fonctionnalité en utilisant les deux. Contrairement à la tâche asynchrone, le service a son propre cycle de vie et hérite du contexte (le service est plus robuste qu'une tâche asynchrone). Le service peut s'exécuter même si vous avez quitté l'application. Si vous voulez faire quelque chose même après la fermeture de l'application et que vous avez également besoin de la variable de contexte, vous opterez pour Service.

Exemple: si vous souhaitez lire une musique et que vous ne souhaitez pas mettre en pause si l'utilisateur quitte l'application, vous opterez certainement pour le service.

sayem siam
la source
1

Comparaison d'un service de classe de base local, en cours de traitement ✱ à un AsyncTask:

✱ (Cette réponse ne concerne pas les services exportés, ni aucun service qui s'exécute dans un processus différent de celui du client, car les cas d'utilisation attendus diffèrent considérablement de ceux d'un AsyncTask. Aussi, dans un souci de concision, la nature de certains Servicesous - classes (par exemple IntentService, JobService) seront ignorées ici.)

Durée de vie du processus

A Servicereprésente, pour l'OS, "le désir d'une application d'effectuer une opération de plus longue durée sans interagir avec l'utilisateur" [ ref ].

Pendant que vous Serviceexécutez, Android comprend que vous ne voulez pas que votre processus soit tué. Cela est également vrai chaque fois que vous avez un Activityécran, et cela est particulièrement vrai lorsque vous exécutez un service de premier plan . (Lorsque tous les composants de votre application disparaissent, Android pense: "Oh, c'est le bon moment pour tuer cette application, afin que je puisse libérer des ressources".)

En outre, en fonction de la dernière valeur de retour de Service.onCreate(), Android peut tenter de "relancer" les applications / services qui ont été tués en raison de la pression des ressources [ ref ].

AsyncTasksne faites rien de tout cela. Peu importe le nombre de threads d'arrière-plan que vous exécutez ou leur travail: Android ne maintiendra pas votre application en vie simplement parce que votre application utilise le processeur. Il doit avoir un moyen de savoir que votre application a encore du travail à faire; c'est pourquoi Servicessont enregistrés avec le système d'exploitation et AsyncTasksne le sont pas.

Multithreading

AsyncTasks il s'agit de créer un thread d'arrière-plan sur lequel effectuer le travail, puis de présenter le résultat de ce travail au thread d'interface utilisateur de manière threadsafe.

Chaque nouvelle AsyncTaskexécution entraîne généralement plus de concurrence (plus de threads), sous réserve des limitations du AsyncTasks'sthread-pool [ ref ].

Serviceles méthodes, en revanche, sont toujours appelées sur le thread d'interface utilisateur [ ref ]. Cela vaut à onCreate(), onStartCommand(), onDestroy(), onServiceConnected(), etc. Donc, dans un certain sens, Servicesne le font pas « run » en arrière - plan. Une fois qu'ils ont démarré ( onCreate()), ils sont simplement "assis" là - jusqu'à ce qu'il soit temps de nettoyer, d'exécuter un onStartCommand(), etc.

En d'autres termes, l'ajout supplémentaire Servicesn'entraîne pas plus de concurrence. Les méthodes de service ne sont pas un bon endroit pour effectuer de grandes quantités de travail, car elles s'exécutent sur le thread d'interface utilisateur .

Bien sûr, vous pouvez étendre Service, ajouter vos propres méthodes et les appeler à partir de n'importe quel thread de votre choix. Mais si vous faites cela, la responsabilité de la sécurité des threads incombe à vous - pas au cadre.

Si vous souhaitez ajouter un thread d'arrière-plan (ou une autre sorte de worker) à votre Service, vous êtes libre de le faire. Vous pouvez démarrer un thread d'arrière-plan / AsyncTaskin Service.onCreate(), par exemple. Mais tous les cas d'utilisation ne l'exigent pas. Par exemple:

  • Vous souhaiterez peut-être continuer à Servicefonctionner afin de pouvoir continuer à obtenir des mises à jour de localisation en «arrière-plan» (c'est-à-dire sans nécessairement en avoir à l' Activitiesécran).
  • Ou, vous pouvez garder votre application en vie juste pour que vous puissiez conserver un BroadcastReceiverenregistrement "implicite" à long terme (après l'API 26, vous ne pouvez pas toujours le faire via le manifeste, vous devez donc vous inscrire au moment de l'exécution. [ réf ]).

Aucun de ces cas d'utilisation ne nécessite une grande activité du processeur; ils exigent simplement que l'application ne soit pas tuée .

En tant que travailleurs

Servicesne sont pas axés sur les tâches. Ils ne sont pas configurés pour «exécuter une tâche» et «fournir un résultat», comme le AsyncTaskssont. Servicesne résolvez aucun problème de sécurité des threads (nonobstant le fait que toutes les méthodes s'exécutent sur un seul thread). AsyncTasks, d'un autre côté, gérez cette complexité pour vous.

Notez qu'il AsyncTaskest prévu de devenir obsolète . Mais cela ne signifie pas que vous devriez remplacer le vôtre AsyncTaskspar Services! (Si vous avez appris quelque chose de cette réponse, cela devrait être clair.)

TL; DR

Servicessont pour la plupart là pour «exister». Ils sont comme un hors écran Activity, fournissant une raison pour que l'application reste en vie, tandis que d'autres composants se chargent de faire le «travail». AsyncTasks«travailler», mais ils ne maintiendront pas en eux-mêmes un processus en vie.

greeble31
la source