Je me suis un peu confus au sujet des différences entre Handlers
, AsyncTask
et Threads
dans Android. J'ai lu pas mal de blogs et de questions ici dans StackOverflow.
Handler
sont des fils 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 via Handler
. L'utilisation des gestionnaires vous offre l'avantage MessagingQueues
, donc si vous souhaitez planifier des messages ou mettre à jour plusieurs éléments d'interface utilisateur ou effectuer des tâches répétitives.
AsyncTask
sont similaires, en fait, ils utilisent Handler
, mais ne s'exécutent pas dans le thread d'interface utilisateur, c'est donc bon 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
cependant ne peut pas interagir avec l'interface utilisateur, fournir un filetage plus "basique" et vous manquez toutes les abstractions de AsyncTask
.
Cependant, je voudrais avoir une connexion socket exécutée en service. Si cela doit être exécuté dans un gestionnaire ou un thread, ou même unAsyncTask
? L'interaction avec l'interface utilisateur n'est pas du tout nécessaire. Cela fait-il une différence en termes de performances que j'utilise?
Pendant ce temps, la documentation a été considérablement améliorée.
Handler
n'est pas un thread et n'exécute rien. Ce n'est qu'un moyen de transmettre en toute sécurité des messages d'un thread à la file d'attente de messages d'un autre thread . Donc, normalement, (au moins) deux threads doivent toujours être créés qui peuvent ensuite utiliser un gestionnaire, mais le gestionnaire ne peut rien exécuter lui-même.Réponses:
En tant que tutoriel sur le traitement d'arrière-plan Android avec les gestionnaires, AsyncTask et les chargeurs sur le site Vogella:
le
Handler
classe peut être utilisée pour s'inscrire à un thread et fournit un canal simple pour envoyer des données à ce thread.le
AsyncTask
classe encapsule la création d'un processus d'arrière-plan et la synchronisation avec le thread principal. Il prend également en charge la génération de rapports sur la progression des tâches en cours d'exécution.Et a
Thread
est fondamentalement l'élément central du multithreading qu'un développeur peut utiliser avec l'inconvénient suivant:Et en ce qui concerne le
AsyncTask
, comme le dit la référence du développeur Android :Mise à jour de mai 2015: j'ai trouvé une excellente série de conférences couvrant ce sujet.
Important: Si vous êtes à un point où vous envisagez d'utiliser
AsyncTask
pour résoudre vos problèmes de filetage, vous devez d' abord vérifierReactiveX/RxAndroid
pour un modèle de programmation peut - être plus approprié. Une très bonne ressource pour obtenir un aperçu est l' apprentissage de RxJava 2 pour Android par exemple .la source
Si nous regardons le code source, nous verrons
AsyncTask
etHandler
est purement écrit en Java. (Il y a cependant quelques exceptions. Mais ce n'est pas un point important)Il n'y a donc pas de magie dans
AsyncTask
ouHandler
. Ces cours nous facilitent la vie en tant que développeur.Par exemple: si le programme A appelle la méthode A (), la méthode A () peut s'exécuter dans un thread différent avec le programme A. Nous pouvons facilement vérifier en utilisant le code suivant:
Pourquoi devrions-nous utiliser un nouveau thread pour certaines tâches? Vous pouvez google pour cela. De nombreuses raisons, par exemple: levage lourd, travaux de longue durée.
Alors, quelles sont les différences entre
Thread
,AsyncTask
etHandler
?AsyncTask
etHandler
sont écrits en Java (en interne, ils utilisent unThread
), donc tout ce que nous pouvons faire avecHandler
ouAsyncTask
, nous pouvons réaliser en utilisant unThread
aussi.Qu'est-ce qui peut
Handler
et peutAsyncTask
vraiment aider?La raison la plus évidente est la communication entre le thread appelant et le thread travailleur. ( Fil de l'appelant : Un fil qui appelle le fil de travail pour effectuer certaines tâches. Un fil de l'appelant ne doit pas nécessairement être le fil de l'interface utilisateur). Bien sûr, nous pouvons communiquer entre deux threads de différentes manières, mais il existe de nombreux inconvénients (et dangers) en raison de la sécurité des threads.
C'est pourquoi nous devrions utiliser
Handler
etAsyncTask
. Ces classes font la plupart du travail pour nous, nous avons seulement besoin de savoir quelles méthodes remplacer.La différence entre
Handler
etAsyncTask
est: à utiliserAsyncTask
lorsque le thread de l'appelant est un thread d'interface utilisateur . Voici ce que dit le document Android:Je veux souligner deux points:
1) Utilisation facile du thread d'interface utilisateur (donc, utilisez lorsque le thread d'appelant est le thread d'interface utilisateur).
2) Pas besoin de manipuler les gestionnaires. (signifie: vous pouvez utiliser Handler au lieu d'AsyncTask, mais AsyncTask est une option plus simple).
Il y a beaucoup de choses dans ce post que je n'ai pas encore dites, par exemple: qu'est-ce que le thread d'interface utilisateur, ou pourquoi c'est plus facile. Vous devez connaître certaines méthodes derrière chaque classe et les utiliser, vous en comprendrez parfaitement la raison.
@: lorsque vous lirez le document Android, vous verrez:
Cette description peut sembler étrange au premier abord. Nous devons seulement comprendre que chaque thread a chaque file d'attente de messages (comme une liste de tâches), et le thread prendra chaque message et le fera jusqu'à ce que la file d'attente de messages soit vide (tout comme nous terminons notre travail et nous couchons). Donc quand
Handler
communique, il donne simplement un message au thread appelant et attendra d'être traité.Compliqué? N'oubliez pas que cela
Handler
peut communiquer avec le fil de l'appelant en toute sécurité.la source
Après avoir regardé en profondeur, c'est simple.
AsyncTask
:C'est un moyen simple d'utiliser un thread sans rien savoir du modèle de thread java .
AsyncTask
donne divers rappels respectifs au thread de travail et au thread principal.À utiliser pour les petites opérations en attente comme les suivantes:
Handler
:Lorsque nous installons une application dans Android, il crée un thread pour cette application appelé MAIN UI Thread. Toutes les activités s'exécutent à l'intérieur de ce fil. Selon la règle du modèle de thread unique Android, nous ne pouvons pas accéder directement aux éléments d'interface utilisateur (bitmap, textview, etc.) pour un autre thread défini à l'intérieur de cette activité.
Un gestionnaire vous permet de communiquer avec le thread d'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 d'interface utilisateur. Un gestionnaire peut envoyer et traiter des objets Message et Runnable associés à MessageQueue d'un thread. Chaque instance de gestionnaire est associée à un seul thread et à la file d'attente de messages de ce thread. Lorsqu'un nouveau gestionnaire est créé, il est lié à la file d'attente des threads / messages du thread qui le crée.
C'est le meilleur choix pour:
Thread
:Il est maintenant temps de parler du fil.
Le thread est le parent des deux
AsyncTask
etHandler
. Ils utilisent tous deux en interne un thread, ce qui signifie que vous pouvez également créer votre propre modèle de thread commeAsyncTask
etHandler
, mais cela nécessite une bonne connaissance de l' implémentation multi-threading de Java .la source
Un
AsyncTask
est utilisé pour effectuer des calculs d'arrière-plan et publier le résultat sur le thread d'interface utilisateur (avec des mises à jour de progression facultatives). Puisque vous n'êtes pas concerné par l'interface utilisateur, unHandler
ouThread
semble plus approprié.Vous pouvez frayer un arrière - plan
Thread
et transmettre des messages de retour à votre thread principal en utilisant leHandler
depost
méthode.la source
Fil
Android prend en charge les threads Java standard . Vous pouvez utiliser les threads standard et les outils du package «
java.util.concurrent
» pour mettre les actions en arrière-plan. La seule limitation est que vous ne pouvez pas mettre à jour directement l'interface utilisateur à partir d'un processus d'arrière-plan.Si vous devez mettre à jour l'interface utilisateur à partir d'une tâche d'arrière-plan, vous devez utiliser certaines classes spécifiques à Android. Vous pouvez utiliser la classe "
android.os.Handler
» pour cela ou la classe «AsyncTask
»Gestionnaire
La classe «
Handler
» peut mettre à jour l'interface utilisateur. Un handle fournit des méthodes pour recevoir des messages et pour les runnables. Pour utiliser un gestionnaire, vous devez le sous-classer et le remplacerhandleMessage()
pour traiter les messages. Pour traiterRunable
, vous pouvez utiliser la méthodepost();
Vous n'avez besoin que d'une seule instance d'un gestionnaire dans votre activité.Votre thread peut publier des messages via la méthode
sendMessage(Message msg)
ousendEmptyMessage
.AsyncTask
Si vous en avez un
Activity
qui doit télécharger du contenu ou effectuer des opérations qui peuvent être effectuées en arrière-planAsyncTask
vous permet de maintenir une interface utilisateur réactive et de publier la progression de ces opérations à l'utilisateur.Pour plus d'informations, vous pouvez consulter ces liens.
http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/
http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask
la source
Thread
:Vous pouvez utiliser le nouveau
Thread
pour les tâches d'arrière-plan de longue durée sans impact sur le thread d'interface utilisateur. À partir de Java Thread, vous ne pouvez pas mettre à jour le thread d'interface utilisateur.Étant donné que le thread normal n'est pas très utile pour l'architecture Android, des classes d'assistance pour le thread ont été introduites.
Vous pouvez trouver des réponses à vos questions dans Threading performance page de documentation des .
Gestionnaire :
A
Handler
vous permet d'envoyer et de traiter des messages et desRunnable
objets associés à un threadMessageQueue
. ChaqueHandler
instance est associée à un seul thread et à la file d'attente de messages de ce thread.Il y a deux utilisations principales pour un
Handler
:Pour planifier des messages et des runnables à exécuter à un moment donné dans le futur;
Pour mettre en file d'attente une action à exécuter sur un thread différent du vôtre.
AsyncTask :
AsyncTask
permet une utilisation correcte et facile du thread d'interface utilisateur. Cette classe vous permet d'effectuer des opérations d'arrière-plan et de publier des résultats sur le thread d'interface utilisateur sans avoir à manipuler des threads et / ou des gestionnaires.Désavantages:
Par défaut, une application pousse tous les
AsyncTask
objets qu'elle crée dans un seul thread. Par conséquent, ils s'exécutent en mode série et, comme avec le thread principal, un paquet de travail particulièrement long peut bloquer la file d'attente. Pour cette raison, utilisez AsyncTask pour gérer les éléments de travail d'une durée inférieure à 5 ms .AsyncTask
les objets sont également les contrevenants les plus courants pour les problèmes de référence implicite.AsyncTask
les objets présentent également des risques liés aux références explicites.HandlerThread :
Vous devrez peut-être une approche plus traditionnelle pour exécuter un bloc de travail sur un thread de longue durée ( contrairement à AsyncTask, qui devrait être utilisé pour une charge de travail de 5 ms ), et une certaine capacité à gérer ce flux de travail manuellement. Un thread de gestionnaire est effectivement un thread de longue durée qui récupère le travail d'une file d'attente et opère dessus.
ThreadPoolExecutor :
Cette classe gère la création d'un groupe de threads, définit leurs priorités et gère la répartition du travail entre ces threads. À mesure que la charge de travail augmente ou diminue, la classe tourne ou détruit plus de threads pour s'adapter à la charge de travail.
Si la charge de travail est plus importante et que le célibataire
HandlerThread
ne suffit pas, vous pouvez opter pourThreadPoolExecutor
Étant donné que l'interaction avec l'interface utilisateur n'est pas requise, vous ne pouvez pas y aller
AsyncTask
. Les threads normaux ne sont pas très utiles et sont doncHandlerThread
la meilleure option. Puisque vous devez maintenir la connexion de socket, le gestionnaire sur le thread principal n'est pas du tout utile. Créez unHandlerThread
et obtenez-en un àHandler
partir du looper deHandlerThread
.Si vous souhaitez communiquer avec le thread d'interface utilisateur, vous pouvez utiliser un gestionnaire supplémentaire pour traiter la réponse.
dans votre
Runnable
, vous pouvez ajouterPlus de détails sur la mise en œuvre peuvent être trouvés ici:
Android: Toast dans un fil
la source
À mon avis, les threads ne sont pas le moyen le plus efficace de faire des connexions de socket mais ils fournissent le plus de fonctionnalités en termes d'exécution de threads. Je dis cela parce que, par expérience, l'exécution de threads pendant une longue période entraîne des appareils très chauds et gourmands en ressources. Même un simple
while(true)
chauffera un téléphone en quelques minutes. Si vous dites que l'interaction avec l'interface utilisateur n'est pas importante, c'est peut-être uneAsyncTask
bonne chose car elles sont conçues pour des processus à long terme. Ce n'est que mon avis là-dessus.MISE À JOUR
Veuillez ignorer ma réponse ci-dessus! J'ai répondu à cette question en 2011, alors que j'étais beaucoup moins expérimenté dans Android que maintenant. Ma réponse ci-dessus est trompeuse et est considérée comme erronée. Je le laisse là parce que beaucoup de gens l'ont commenté ci-dessous en me corrigeant, et j'ai appris ma leçon.
Il y a de bien meilleures réponses sur ce sujet, mais je vais au moins me donner une réponse plus appropriée. Il n'y a rien de mal à utiliser un Java standard
Thread
; cependant, vous devez vraiment faire attention à la façon dont vous l'implémentez, car une mauvaise exécution peut être très gourmande en processeur (le symptôme le plus notable peut être le réchauffement de votre appareil).AsyncTask
s sont assez idéales pour la plupart des tâches que vous souhaitez exécuter en arrière-plan (des exemples courants sont les E / S disque, les appels réseau et les appels de base de données). Cependant, lesAsyncTask
s ne doivent pas être utilisés pour des processus particulièrement longs qui peuvent devoir se poursuivre après que l'utilisateur a fermé votre application ou mis son appareil en veille. Je dirais que pour la plupart des cas, tout ce qui n'appartient pas au thread d'interface utilisateur peut être pris en charge dans unAsyncTask
.la source
AsyncTask
est conçu pour effectuer pas plus de quelques secondes d'opération à effectuer en arrière-plan (déconseillé pour les mégaoctets de téléchargement de fichiers à partir du serveur ou pour calculer une tâche intensive de processeur telle que les opérations d'E / S de fichiers). Si vous devez exécuter une opération de longue durée, il vous a été fortement conseillé d'utiliser des threads natifs java. Java vous propose différentes classes liées aux threads pour faire ce dont vous avez besoin. UtilisezHandler
pour mettre à jour le thread d'interface utilisateur.la source
la source
Permettez-moi d'essayer de répondre à la question ici avec un exemple :) - MyImageSearch [Veuillez renvoyer l'image ici de l'écran d'activité principal - contenant un texte d'édition / bouton de recherche / vue de grille]
Description de MyImageSearch - Une fois que l'utilisateur entre les détails dans le champ d'édition de texte et clique sur le bouton de recherche, nous rechercherons des images sur Internet via les services Web fournis par flickr (il vous suffit de vous y inscrire pour obtenir une clé / un jeton secret) - pour la recherche, nous envoyons une demande HTTP et récupérons les données JSON en réponse contenant les URL des images individuelles que nous utiliserons ensuite pour charger la vue de la grille.
Mon implémentation - Dans l'activité principale, je définirai une classe interne qui étend la tâche AsyncTask pour envoyer la demande HTTP dans la méthode doInBackGround et récupérer la réponse JSON et mettre à jour ma liste de tableaux locale de FlickrItems que je vais utiliser pour mettre à jour ma GridView via le FlickrAdapter (étend le BaseAdapter) et appelez l'adaptateur.notifyDataSetChanged () dans onPostExecute () d'AsyncTask pour recharger la vue de la grille. Notez qu'ici, la requête HTTP est un appel bloquant à cause duquel je l'ai fait via AsyncTask. Et, je peux mettre en cache les éléments dans l'adaptateur pour augmenter les performances ou les stocker sur SDCard. La grille que je vais gonfler dans le FlickrAdapter contient dans mon implémentation une barre de progression et une vue d'image. Ci-dessous, vous pouvez trouver le code de mainActivity que j'ai utilisé.
Réponse à la question maintenant - Donc, une fois que nous avons les données JSON pour récupérer des images individuelles, nous pouvons implémenter la logique de mise en arrière-plan des images via des gestionnaires ou des threads ou AsyncTask. Nous devons noter ici que puisque mes images une fois téléchargées doivent être affichées sur l'interface utilisateur / thread principal, nous ne pouvons pas simplement utiliser les threads tels quels car ils n'ont pas accès au contexte. Dans FlickrAdapter, les choix auxquels je pouvais penser:
Voici le code source:
J'espère que ma réponse, bien que longue, aidera à comprendre certains des détails les plus fins.
la source
Cela dépend lequel choisir en fonction de l'exigence
Le gestionnaire est principalement utilisé pour passer d'un autre thread au thread principal, le gestionnaire est attaché à un looper sur lequel il publie sa tâche exécutable dans la file d'attente. Donc, si vous êtes déjà dans un autre thread et passez au thread principal, vous devez gérer au lieu d'une tâche asynchrone ou d'un autre thread
Si le gestionnaire créé dans un thread autre que le thread principal qui n'est pas un boucleur ne donnera pas d'erreur lorsque le handle est créé le thread, ce thread doit être transformé en lopper.
AsyncTask est utilisé pour exécuter du code pendant quelques secondes qui s'exécute sur le thread d'arrière-plan et donne son résultat au thread principal ** * Limitations AsyncTask 1. La tâche Async n'est pas attachée au cycle de vie de l'activité et continue de s'exécuter même si son activité est détruite alors que le chargeur ne le fait pas 'ai pas cette limitation 2. Toutes les tâches asynchrones partagent le même thread d'arrière-plan pour l'exécution, ce qui a également un impact sur les performances de l'application
Le fil est également utilisé dans l'application pour le travail en arrière-plan, mais il n'a aucun rappel sur le fil principal. Si l'exigence convient à certains threads au lieu d'un thread et qui doivent exécuter la tâche plusieurs fois, l'exécuteur du pool de threads est la meilleure option.
la source
Fil
Lorsque vous démarrez une application, un processus est créé pour exécuter le code. Pour utiliser efficacement les ressources informatiques, les threads peuvent être démarrés dans le processus afin que plusieurs tâches puissent être exécutées à la fois. Les threads vous permettent donc de créer des applications efficaces en utilisant efficacement le processeur sans temps d'inactivité.
Dans Android, tous les composants s'exécutent sur un seul thread principal appelé. Tâches de file d'attente du système Android et exécutez-les une par une sur le thread principal. Lorsque de longues tâches sont exécutées, l'application ne répond plus.
Pour éviter cela, vous pouvez créer des threads de travail et exécuter des tâches d'arrière-plan ou de longue durée.
Gestionnaire
Étant donné qu'Android utilise un modèle de thread unique, les composants d'interface utilisateur sont créés non sûrs, ce qui signifie que le thread qu'il a créé doit y accéder, ce qui signifie que le composant d'interface utilisateur doit être mis à jour uniquement sur le thread principal. Comme le composant d'interface utilisateur s'exécute sur le thread principal, les tâches qui s'exécutent sur les threads de travail ne peuvent pas modifier les composants d'interface utilisateur. C'est là que Handler entre en scène. Le gestionnaire à l'aide de Looper peut se connecter à un nouveau thread ou à un thread existant et exécuter le code qu'il contient sur le thread connecté.
Le gestionnaire permet la communication entre les threads. À l'aide de Handler, le thread d'arrière-plan peut lui envoyer des résultats et le gestionnaire connecté au thread principal peut mettre à jour les composants de l'interface utilisateur sur le thread principal.
AsyncTask
AsyncTask fourni par Android utilise à la fois le thread et le gestionnaire pour faciliter l'exécution de tâches simples en arrière-plan et la mise à jour des résultats du thread d'arrière-plan vers le thread principal.
Veuillez consulter les threads Android, les gestionnaires, les tâches asynctasques et les pools de threads pour des exemples.
la source
Handler
- est un moyen de communication entre les threads. Dans Android, il est principalement utilisé pour communiquer avec le thread principal en créant et en envoyant des messages via le gestionnaireAsyncTask
- est utilisé pour exécuter des applications de longue durée dans un thread d'arrière-plan. Avec n,AsyncTask
vous pouvez effectuer l'opération dans un thread d'arrière-plan et obtenir le résultat dans le thread principal de l'application.Thread
- est un processus léger, pour atteindre la simultanéité et une utilisation maximale du processeur. Dans Android, vous pouvez utiliser le fil pour effectuer des activités qui ne touchent pas à l'interface utilisateur de l'applicationla source