397 votes

Handler vs AsyncTask vs Thread

Je suis un peu confus quant aux différences entre Handlers , AsyncTask y Threads dans Android. J'ai lu pas mal de blogs et de questions ici sur StackOverflow.

Handler sont des threads d'arrière-plan qui vous permettent de communiquer avec l'interface utilisateur. La mise à jour d'une barre de progression, par exemple, doit être effectuée par l'intermédiaire de Handler . En utilisant les Handlers, vous avez l'avantage de MessagingQueues Ainsi, si vous souhaitez programmer des messages, mettre à jour plusieurs éléments d'interface utilisateur ou avoir des tâches répétitives.

AsyncTask sont similaires, en fait, ils font appel à Handler Il est donc idéal pour récupérer des données, par exemple pour récupérer des services Web. Plus tard, vous pourrez interagir avec l'interface utilisateur.

Thread ne peut cependant pas interagir avec l'interface utilisateur, fournir un threading plus "basique" et vous manquez toutes les abstractions de AsyncTask .

Cependant, je voudrais qu'une connexion socket soit exécutée en service. Doit-elle être exécutée dans un gestionnaire ou un thread, ou même dans un fichier de type AsyncTask ? L'interaction avec l'interface utilisateur n'est pas du tout nécessaire. Cela fait-il une différence en termes de performances de ce que j'utilise ?

Pendant ce temps, le documentation a été grandement amélioré.

1 votes

10 votes

"Les gestionnaires sont des threads d'arrière-plan" - Certaines des réponses les plus votées semblent également aller dans ce sens. Mais c'est une idée fausse. A Handler n'est pas un thread, et il n'exécute rien. Il s'agit uniquement d'un moyen de transmettre en toute sécurité des messages d'un processus à un autre. filetage à la file d'attente des messages d'un autre filetage . Donc, normalement, (au moins) deux fils doivent encore être créés qui peuvent ensuite utiliser un gestionnaire, mais le gestionnaire ne peut rien exécuter lui-même.

359voto

hqt Points 5356

Si nous regardons le code source, nous verrons AsyncTask y Handler est purement écrit en Java. (Il y a cependant quelques exceptions, mais ce n'est pas un point important).

Donc il n'y a pas de magie dans AsyncTask o Handler . Ces classes nous facilitent la vie en tant que développeur.

Par exemple : Si le programme A appelle la méthode A(), la méthode A() pourrait s'exécuter dans un thread différent du programme A. Nous pouvons facilement le vérifier avec le code suivant :

Thread t = Thread.currentThread();    
int id = t.getId();

Pourquoi devrions-nous utiliser un nouveau fil de discussion pour certaines tâches ? Vous pouvez le chercher sur Google. Il y a de nombreuses raisons, par exemple : le levage lourd, les travaux de longue haleine.

Alors, quelles sont les différences entre Thread , AsyncTask et Handler ?

AsyncTask y Handler sont écrites en Java (en interne, elles utilisent un module Thread ), donc tout ce que nous pouvons faire avec Handler o AsyncTask nous pouvons réaliser en utilisant un Thread aussi.

Que peut Handler y AsyncTask aide vraiment ?

La raison la plus évidente est la communication entre le thread de l'appelant et le thread du travailleur. ( Fil d'appel : Un thread qui appelle le Fil de travail pour effectuer certaines tâches. Un thread appelant ne doit pas nécessairement être le thread de l'interface utilisateur). Bien sûr, nous pouvons communiquer entre deux threads d'autres manières, mais la sécurité des threads présente de nombreux inconvénients (et dangers).

C'est pourquoi nous devrions utiliser Handler y AsyncTask . Ces classes font le gros du travail pour nous, nous devons seulement savoir quelles méthodes surcharger.

La différence entre Handler y AsyncTask est : Utilisez AsyncTask quand Fil conducteur es un Fil conducteur de l'interface utilisateur . C'est ce que dit le document Android :

AsyncTask permet d'utiliser correctement et facilement le thread de l'interface utilisateur. Cette classe permet d'effectuer des opérations en arrière-plan et de publier les résultats sur l'interface utilisateur. sans avoir à manipuler les threads et/ou les handlers.

Je voudrais insister sur deux points :

1) Utilisation facile du thread UI (donc, utilisation lorsque le thread de l'appelant est le thread UI).

2) Pas besoin de manipuler les manipulateurs. (signifie : Vous pouvez utiliser Handler au lieu d'AsyncTask, mais AsyncTask est une option plus facile).

Il y a beaucoup de choses dans ce billet que je n'ai pas encore dites, par exemple : qu'est-ce que UI Thread, ou pourquoi c'est plus facile. Vous devez connaître quelques méthodes derrière chaque classe et l'utiliser, vous comprendrez complètement la raison.

@ : lorsque vous lisez le document Android, vous verrez :

Le gestionnaire vous permet d'envoyer et de traiter les objets Message et Runnable. associés à la MessageQueueue d'un thread.

Cette description peut sembler étrange au premier abord. Il suffit de comprendre que chaque thread dispose d'une file d'attente de messages (comme une liste de tâches), et que le thread prendra chaque message et l'exécutera jusqu'à ce que la file d'attente de messages soit vide (tout comme nous finissons notre travail et allons nous coucher). Ainsi, lorsque Handler communique, il donne juste un message au thread appelant et il attendra le traitement.

Compliqué ? Rappelez-vous simplement que Handler peut communiquer avec le thread de l'appelant en toute sécurité.

4 votes

En fait, asynctask est également basé sur handler et futuretask, voir

0 votes

AsyncTask est essentiellement une classe d'aide construite au-dessus de Handler et Thread. developer.Android.com/reference/Android/os/AsyncTask.html . Regardez la doc "AsyncTask est conçu pour être une classe d'aide autour de Thread et Handler". AsyncTask est sorti dans l'API3 alors que Handler existe depuis l'API1.

56voto

Lavekush Agrawal Points 1754

Après un examen approfondi, c'est simple.

AsyncTask :

C'est un moyen simple d'utiliser un fil. sans rien savoir du modèle de fil de java . AsyncTask donne divers rappels respectifs au fil de travail et au fil principal.

A utiliser pour les petites opérations d'attente comme les suivantes :

  1. Récupération de certaines données à partir de services web et affichage sur la mise en page.
  2. Requête de base de données.
  3. Quand vous réalisez qu'une opération courante ne sera jamais, jamais imbriquée.

Handler :

Lorsque nous installons une application dans Android, celui-ci crée un thread pour cette application appelé MAIN UI Thread. Toutes les activités s'exécutent dans ce thread. Selon la règle du modèle de fil unique d'Android, nous ne pouvons pas accéder aux éléments de l'interface utilisateur (bitmap, vue de texte, etc.) directement pour un autre fil défini dans cette activité.

Un Handler vous permet de communiquer avec le thread de l'interface utilisateur à partir d'autres threads d'arrière-plan. Ceci est utile dans Android, car Android ne permet pas aux autres threads de communiquer directement avec le thread UI. Un Handler peut envoyer et traiter des objets Message et Runnable associés à la MessageQueueue d'un thread. Chaque instance de Handler est associée à un seul thread et à la file d'attente de messages de ce thread. Lorsqu'un nouveau Handler est créé, il est lié au thread/à la file d'attente de messages du thread qui le crée.

C'est la meilleure solution pour :

  1. Il permet de mettre en file d'attente les messages.
  2. Programmation des messages.

Thread :

Maintenant, il est temps de parler du fil.

Le fil est le parent des deux AsyncTask y Handler . Ils utilisent tous deux en interne le thread, ce qui signifie vous pouvez également créer votre propre modèle de fil comme AsyncTask y Handler mais cela nécessite une bonne connaissance de L'implémentation du multithreading de Java .

1 votes

L'api AsyncTask est, en fait, écrite avec des Futures, des Handlers et des Executors. Voir le code source : grepcode.com/file_/repository.grepcode.com/java/ext/

22voto

unluddite Points 2094

Un site AsyncTask est utilisé pour effectuer des calculs en arrière-plan et publier le résultat dans le thread de l'interface utilisateur (avec des mises à jour de progression facultatives). Puisque vous n'êtes pas concerné par l'interface utilisateur, alors une fonction Handler o Thread semble plus approprié.

Vous pouvez créer un arrière-plan Thread et renvoyer des messages à votre thread principal en utilisant la fonction Handler 's post méthode.

5voto

Brian Points 2771

À mon avis, les threads ne sont pas le moyen le plus efficace de réaliser des connexions de socket, mais ils offrent le plus de fonctionnalités en termes de fonctionnement des threads. Je dis cela parce que, d'après mon expérience, l'exécution de threads pendant une longue période fait que les périphériques sont très chauds et consomment beaucoup de ressources. Même un simple while(true) va chauffer un téléphone en quelques minutes. Si vous dites que l'interaction avec l'interface utilisateur n'est pas importante, peut-être qu'une AsyncTask est bonne car elle est conçue pour des processus à long terme. Ce n'est que mon avis sur la question.

UPDATE

Veuillez ne pas tenir compte de ma réponse ci-dessus ! J'ai répondu à cette question en 2011, alors que j'étais beaucoup moins expérimenté que maintenant en matière d'Android. Ma réponse ci-dessus est trompeuse et est considérée comme erronée. Je la laisse là parce que de nombreuses personnes l'ont commentée ci-dessous en me corrigeant, et j'ai appris ma leçon.

Il y a d'autres réponses bien meilleures sur ce fil, mais je vais au moins me donner une réponse plus appropriée. Il n'y a rien de mal à utiliser une version normale de Java Thread Cependant, vous devez faire très attention à la manière dont vous l'implémentez, car une mauvaise mise en œuvre peut être très gourmande en ressources processeur (le symptôme le plus notable peut être le réchauffement de votre appareil). AsyncTask sont idéales pour la plupart des tâches que vous souhaitez exécuter en arrière-plan (les exemples courants sont les entrées/sorties de disque, les appels réseau et les appels de base de données). Cependant, AsyncTask ne doivent pas être utilisés pour des processus particulièrement longs qui pourraient devoir se poursuivre après que l'utilisateur a fermé votre application ou mis son appareil en veille. Je dirais que dans la plupart des cas, tout ce qui n'a pas sa place dans le thread de l'interface utilisateur peut être pris en charge dans un thread de l'interface utilisateur. AsyncTask .

0 votes

Merci. Y a-t-il vraiment une raison pour laquelle je devrais utiliser les Threads au lieu des AsyncTasks ? Ou est-il plus recommandé de s'en servir ?

0 votes

Eh bien, il semble que vous compreniez partiellement AsyncTasks vous-même. Les AsyncTasks sont particulièrement utiles pour les tâches à long terme et exigeantes en termes de processeur. Vous pourriez utiliser un Thread, qui est ce que j'ai utilisé sur ma première application qui utilisait des sockets, mais par expérience, j'ai trouvé que les Threads sont très gourmands en processeur pour la quantité de travail qu'ils sont censés faire. Ce n'est peut-être pas la bonne raison, mais les AsyncTasks semblent plus optimisés pour Android que les Threads.

9 votes

@AeroDroid Dans votre exemple : "un simple while(true)", vous piquerez le CPU ici à moins que vous n'ajoutiez un état de veille dans la boucle. Ceci est vrai pour toute boucle sans fin. Si vous voulez réduire l'utilisation du CPU en raison de cette surcharge, mettez le thread en sommeil pendant quelques millisecondes à la fin de la boucle.

5voto

sky Points 47

AsyncTask est conçu pour effectuer des opérations de quelques secondes au maximum en arrière-plan (il n'est pas recommandé de télécharger des mégaoctets de fichiers à partir d'un serveur ou d'effectuer des tâches gourmandes en ressources informatiques telles que des opérations d'entrée/sortie de fichiers). Si vous devez exécuter une opération de longue durée, il vous est fortement conseillé d'utiliser les threads natifs de Java. Java vous fournit diverses classes liées aux threads pour faire ce dont vous avez besoin. Utilisez Handler pour mettre à jour le fil d'interface utilisateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X