Gestionnaire vs AsyncTask

128

Je ne sais pas quand on choisirait AsyncTask plutôt qu'un gestionnaire. Disons que j'ai du code que je veux exécuter toutes les n secondes qui mettra à jour l'interface utilisateur. Pourquoi choisirais-je l'un plutôt que l'autre?

Steve
la source
1
Cela est devenu plus compliqué avec AsyncTaskLoaders. Voir stackoverflow.com/q/7120813/969325 pour plus d'informations.
Warpzit

Réponses:

75

IMO, AsyncTask a été écrit pour fournir un moyen pratique et facile à utiliser de réaliser un traitement en arrière-plan dans les applications Android, sans trop se soucier des détails de bas niveau (threads, boucles de messages, etc.). Il fournit des méthodes de rappel qui aident à planifier des tâches et également à mettre à jour facilement l'interface utilisateur chaque fois que nécessaire.

Cependant, il est important de noter que lors de l'utilisation d'AsyncTask, un développeur se soumet à ses limitations, qui résultent des décisions de conception prises par l'auteur de la classe. Par exemple, j'ai récemment découvert qu'il y avait une limite au nombre de travaux pouvant être planifiés à l'aide d'AsyncTasks.

Handler est plus transparent des deux et vous donne probablement plus de liberté; donc si vous voulez plus de contrôle sur les choses, vous choisirez Handler, sinon AsynTask fonctionnera très bien.

Samuh
la source
C'est vrai. J'utilisais AsyncTasks pour toutes les opérations d'arrière-plan de mon projet. À un moment donné, j'ai commencé à atteindre cette limite maximale de tâches, de sorte que mes tâches ne commenceraient qu'une fois une autre terminée. En fin de compte, j'ai dû changer toute ma structure pour arrêter d'utiliser les asynctasks et éviter d'atteindre cette limitation.
tbraun
5
À partir de Honeycomb, AsyncTaskssont exécutés sur un thread, donc plus de parallélisme. Vous pouvez toujours les exécuter sur une Executorimplémentation parallèle .
MrSnowflake
63

Ma règle d'or serait:

  • Si vous faites quelque chose d'isolement lié à l'interface utilisateur, par exemple le téléchargement de données à présenter dans une liste, continuez et utilisez AsyncTask.

  • Si vous effectuez plusieurs tâches répétées, par exemple le téléchargement de plusieurs images qui doivent être affichées ImageViews(comme le téléchargement de vignettes) lors du téléchargement, utilisez une file d'attente de tâches avec Handler.

Alexanderblom
la source
Handler est dans le niveau API 1 et ASYNCTASK dans le niveau API 3. sera-t-il obsolète à tout prix? becaz me concentre sur le portage des applications des anciennes versions vers 2.2 et 2.3 ..
yokks
10
Aucun des deux ne sera bientôt obsolète. Handler ne sera jamais obsolète car l'interface utilisateur est essentiellement construite autour de lui.
alexanderblom
Ne devriez-vous pas utiliser un chargeur pour charger les données que votre interface utilisateur doit présenter?
nbarraille
19

Essayez toujours d'éviter d'utiliser AsyncTask lorsque cela est possible, principalement pour les raisons suivantes:

  • AsyncTask n'est pas garanti de s'exécuter car il existe une base ThreadPool et une taille maximale définies par le système et si vous créez trop d'asynctask, elles seront finalement détruites

  • AsyncTask peut être automatiquement arrêté, même en cours d'exécution, en fonction du cycle de vie de l'activité et vous n'avez aucun contrôle dessus

  • Les méthodes AsyncTask exécutées sur le thread d'interface utilisateur, comme onPostExecute, peuvent être exécutées lorsque l'activité à laquelle elle fait référence n'est plus visible ou est peut-être dans un état de disposition différent, comme après un changement d'orientation.

En conclusion, vous ne devriez pas utiliser les méthodes liées à UIThread d'AsyncTask, ce qui est son principal avantage !!! De plus, vous ne devez effectuer que des travaux non critiques sur doInBackground. Lisez ce fil pour plus d'informations sur ces problèmes:

AsyncTask est-il vraiment défectueux sur le plan conceptuel ou est-ce que je manque juste quelque chose?

Pour conclure, essayez de préférer utiliser IntentServices, HandlerThread ou ThreadPoolExecutor au lieu d'AsyncTask lorsque l'un des problèmes mentionnés ci-dessus peut vous préoccuper. Bien sûr, cela nécessitera plus de travail, mais votre application sera plus sûre.

type-a1pha
la source
Ouais, j'ai passé beaucoup de temps à regretter de nombreuses utilisations d'AsyncTasks. Ils semblent super, mais ... tant de problèmes!
SMBiggs
6
Je suis désolé de publier si fortement contre vos points, mais je ne peux pas laisser votre pauvre style effet noobies à Android. Point un. Vous ne devriez PAS avoir autant de threads en cours d'exécution. Si vous rencontrez cela, votre architecture est foobar. Point 2. Comment diable .. D'accord, oui, tout dans Android est un jeu gratuit pour le ramasse-miettes ... Vous ne verriez qu'un comportement abserd comme décrit ci-dessus, dans certains cas strictement abusifs. Point 3. Gérer votre tâche, ne pas être impoli, est une compétence novice. Soit vous le tuez lorsque vous appelez onPause, soit vous le détachez et vous attachez correctement.
StarWind0
1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html C'est tout ce dont vous avez besoin pour apprendre à faire correctement les tâches sans les problèmes ci-dessus (en supposant que vous ne faites pas quelque chose comme cracher quelques centaines de tâches)
StarWind0
16

Si vous voulez faire un calcul toutes les x secondes, vous devriez probablement planifier un Runnablesur a Handler(avec postDelayed()) et cela Runnabledevrait commencer dans le thread d'interface utilisateur actuel. Si vous souhaitez le démarrer dans un autre thread, utilisez HandlerThread. AsyncTask est plus facile à utiliser pour nous mais pas mieux que handler.

MrSnowflake
la source
7

Le gestionnaire est associé au thread principal de l'application. il gère et planifie les messages et les exécutables envoyés depuis les fils d'arrière-plan vers le fil principal de l'application.

AsyncTask fournit une méthode simple pour gérer les threads d'arrière-plan afin de mettre à jour l'interface utilisateur sans la bloquer par des opérations fastidieuses.

La réponse est que les deux peuvent être utilisés pour mettre à jour l'interface utilisateur à partir des threads d'arrière-plan, la différence se situant dans votre scénario d'exécution. Vous pouvez envisager d'utiliser le gestionnaire si vous souhaitez publier des messages différés ou envoyer des messages à MessageQueue dans un ordre spécifique.

Vous pouvez envisager d'utiliser AsyncTask si vous souhaitez échanger des paramètres (mettant ainsi à jour l'interface utilisateur) entre le thread principal de l'application et le thread d'arrière-plan d'une manière simple et pratique.

secretlm
la source
3
Vous pouvez créer votre propre gestionnaire associé à un autre thread.
Aleksejs Mjaliks
Le gestionnaire n'est pas nécessairement lié au thread principal (UI Thread). Il est lié au thread dans lequel il a été instancié et gère les messages ou les exécutables qui arrivent à cette file d'attente de messages de thread. Il peut également envoyer des objets Message et Runnable à cette file d'attente de messages de thread.
azec-pdx
2

AsyncTasksuppose que vous ferez quelque chose sur le thread de l'interface utilisateur, une fois le travail d'arrière-plan terminé. De plus, vous ne pouvez l'exécuter qu'une seule fois (après cela, son statut est FINISHEDet vous obtiendrez une exception essayant de l'exécuter une fois de plus). En outre, la flexibilité de son utilisation n'est pas grande. Oui, vous pouvez utiliser THREAD_POOL_EXECUTORpour une exécution parallèle, mais l'effort pourrait ne pas en valoir la peine.

Handlerne présume rien, sauf la gestion des exécutables et des messages. En outre, il peut être exécuté autant de fois que vous le souhaitez . Vous êtes libre de décider à quel thread il doit être attaché, comment il communique avec les autres gestionnaires, peut-être les produire avec HandlerThread. Donc, c'est beaucoup plus flexible et adapté à certains travaux répétés.

Vérifiez différents types d' Handlerexemples ici .

Lomza
la source
0

Ce sont les meilleures questions d'entrevue qui sont posées. AsyncTask - Ils sont utilisés pour décharger le thread de l'interface utilisateur et effectuer des tâches en arrière-plan. Handlers - Android dosent a un moyen de communication direct entre l'interface utilisateur et le thread d'arrière-plan. Les gestionnaires doivent être utilisés pour envoyer des messages ou exécutables via la file d'attente de messages.

Ainsi, les AsyncTasks sont utilisés lorsque les tâches doivent être exécutées en arrière-plan et les gestionnaires sont utilisés pour la communication entre une interface utilisateur et un thread d'arrière-plan.

saubhagya das
la source
0

doInBackground - fonctionne essentiellement dans un autre thread. onPostExecute - publie les résultats sur le thread d'interface utilisateur et envoie un message en interne au gestionnaire du thread principal. Le thread d'interface utilisateur principal a déjà un looper et un gestionnaire qui lui sont associés.

Donc, fondamentalement, si vous devez effectuer une tâche en arrière-plan, utilisez AsyncTask. Mais finalement, si quelque chose doit être mis à jour sur l'interface utilisateur, il utilisera le gestionnaire du thread principal.

Shinoo Goyal
la source