Handler vs AsyncTask vs Thread

Je me suis légèrement confondu avec les différences entre Handlers , AsyncTask et Threads dans Android. J'ai lu quelques blogs et des questions ici dans 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 devrait être effectuée via Handler . En utilisant Handlers, vous avez l'avantage de MessagingQueues , donc si vous souhaitez planifier des messages ou mettre à jour plusieurs éléments d'IU ou avoir des tâches répétées.

  • Sous-classement JavaScript dans Parse.com
  • Copier un tampon d'octets avec JNI
  • Gradle: ajoute une dépendance pour une saveur spécifique de la bibliothèque
  • Comment puis-je obtenir des informations de latence de la classe AudioTrack d'Android?
  • AudioRecord - Comment obtenir des données dans le tampon?
  • Appeler un AsyncTask à partir d'un autre AsyncTask
  • AsyncTask sont similaires, en fait, ils utilisent Handler , mais ne s'exécute pas dans le thread UI, donc il est bon pour l'extraction de données, par exemple pour la recherche de services Web. Plus tard, vous pouvez interagir avec l'IU.

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

    Cependant, j'aimerais que la connexion socket soit exécutée dans un service. Est-ce que cela devrait être exécuté dans un gestionnaire ou un thread, ou même un AsyncTask ? L'interaction UI n'est pas nécessaire du tout. Est-ce que cela fait une différence en termes de performance que j'utilise?

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

  • Comment obtenir le chemin de carte sdcard interne et externe dans Android
  • Comment utiliser Gradle pour générer des fichiers de projets Eclipse et Intellij pour des projets Android
  • Comment configurer une police pour le menu Options?
  • Message vide de listes Android avec en-tête
  • Mode d'analyse XML (org.w3c.Document) sur Android
  • Réglage du niveau de zoom maximal dans google maps android api v2
  • 10 Solutions collect form web for “Handler vs AsyncTask vs Thread”

    Comme le didacticiel sur le traitement d'arrière-plan Android avec Handlers, AsyncTask et Loaders sur le site Vogella le met:

    La classe Handler peut être utilisée pour vous inscrire à un thread et fournit un canal simple pour envoyer des données sur ce thread.

    La classe AsyncTask encapsule la création d'un processus d'arrière-plan et la synchronisation avec le thread principal. Il prend également en charge la progression des rapports sur les tâches en cours d'exécution.

    Et un Thread est essentiellement l'élément central du multithreading qu'un développeur peut utiliser avec le désavantage suivant:

    Si vous utilisez des threads Java, vous devez gérer les conditions suivantes dans votre propre code:

    • Synchronisation avec le thread principal si vous publiez des résultats retour à l'interface utilisateur
    • Pas de défaut pour annuler le thread
    • Pas de partage de thread par défaut
    • Aucun défaut pour gérer les modifications de configuration dans Android

    Et concernant AsyncTask , comme l' AsyncTask la référence du développeur Android :

    AsyncTask permet une utilisation correcte et facile du thread UI. Cette classe permet d'effectuer des opérations en arrière-plan et de publier des résultats sur le thread UI sans avoir à manipuler des threads et / ou des gestionnaires.

    AsyncTask est conçu pour être une classe d'aide sur Thread and Handler et ne constitue pas un cadre de threading générique. AsyncTasks devrait idéalement être utilisé pour des opérations courtes (quelques secondes au maximum). Si vous devez garder les threads en cours d'exécution pendant de longues périodes, il est fortement recommandé d'utiliser les différentes API fournies par le paquetage java.util.concurrent tel que Executor, ThreadPoolExecutor et FutureTask.

    Mise à jour mai 2015: J'ai trouvé une excellente série de conférences sur ce sujet.

    C'est la recherche de Google: Douglas Schmidt lecture de la simultanéité et de la synchronisation

    C'est la vidéo de la première conférence sur YouTube

    Tout cela fait partie du CS 282 (2013): Programmation des systèmes pour Android de l' Université Vanderbilt . Voici la liste de lecture YouTube

    Douglas Schmidt semble être un excellent conférencier

    Si vous regardez le code source d' AsyncTask and Handler , vous verrez que leur code est écrit uniquement en Java. (Bien sûr, il y a quelques exceptions, mais ce n'est pas un point important.)

    Donc il n'y a pas de magie dans AsyncTask ou Handler . Ils facilitent votre travail 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 avec le programme A. Vous pouvez facilement le vérifier en utilisant:

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

    Pourquoi utiliser un nouveau fil? Vous pouvez google pour cela. Beaucoup de raisons.

    Alors, quelle est la différence entre Thread , AsyncTask et Handler ?

    AsyncTask et Handler sont écrits en Java (en interne, ils utilisent un Thread ), donc tout ce que vous pouvez faire avec Handler ou AsyncTask , vous pouvez également utiliser un Thread .

    Qu'est-ce que Handler et AsyncTask vraiment vous aider?

    La raison la plus évidente est la communication entre le fil d'appel et le thread de travail. ( Fil de l'appelant : un thread qui appelle le fil du travail pour effectuer une tâche. Un fil d'appel ne doit pas nécessairement être le thread de l'interface utilisateur). Bien sûr, vous pouvez communiquer entre deux fils d'autres façons, mais il existe de nombreux inconvénients (et dangers) en raison des problèmes de sécurité du thread.

    C'est pourquoi vous devez utiliser Handler et AsyncTask . Ils font la plupart du travail pour vous, il vous suffit de savoir quelles méthodes utiliser.

    La différence entre Handler et AsyncTask est: Utilisez AsyncTask lorsque le thread de l'appelant est un thread d'interface utilisateur . C'est ce que dit le document Android:

    AsyncTask permet une utilisation correcte et facile du thread UI. Cette classe permet d'effectuer des opérations en arrière-plan et de publier des résultats sur le thread UI sans avoir à manipuler des threads et / ou des gestionnaires

    Je tiens à souligner deux points:

    1) Utilisation facile du thread UI (alors, utilisez lorsque le thread de l'appelant est UI Thread).

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

    Il y a beaucoup de choses dans cette publication que je n'ai pas encore dit, par exemple: qu'est-ce que UI Thread, ou pourquoi c'est plus facile. Vous devez connaître une méthode derrière chaque type et l'utiliser, vous comprendrez complètement pourquoi …

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

    Handler vous permet d'envoyer et de traiter des objets Message et Runnable associés à MessageQueue d'un thread

    Ils peuvent sembler étranges au début. Il suffit de comprendre que chaque thread a chaque file d'attente de messages (comme une liste à faire), et le fil prend chaque message et le fait jusqu'à ce que la file d'attente des messages soit vide (comme vous avez terminé votre travail et vous coucher). Donc, lorsque Handler communique, il donne simplement un message au thread d'appelant et il attendra pour le processus. Compliqué? N'oubliez pas que Handler peut communiquer avec le fil d'appel de manière sécurisée.

    Après avoir examiné en profondeur, c'est tout droit.

    AsyncTask :

    C'est un moyen simple d'utiliser un thread sans rien savoir sur le modèle de thread java . AsyncTask donne différents rappels respectifs au thread de travail et au thread principal.

    Utilisez les petites opérations d'attente comme suit:

    1. Obtenir des données sur les services Web et afficher sur la mise en page.
    2. Requête de base de données.
    3. Lorsque vous vous rendez compte que l'opération de fonctionnement ne sera jamais imbriquée.

    Handler :

    Lorsque nous installons une application dans Android, il crée un thread pour cette application appelée MAIN UI Thread. Toutes les activités se déroulent à l'intérieur de ce fil. Par la règle du modèle de fil unique Android, nous ne pouvons pas accéder aux éléments UI (bitmap, texte, etc.) directement pour un autre thread défini à l'intérieur de cette activité.

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

    C'est le meilleur moyen pour:

    1. Il vous permet de faire des files d'attente de messages.
    2. Programmation des messages.

    Thread :

    Maintenant, il est temps de parler de fil.

    Thread est le parent de AsyncTask et Handler . Ils utilisent à la fois un thread, ce qui signifie que vous pouvez également créer votre propre modèle de fil comme AsyncTask and Handler , mais cela nécessite une bonne connaissance de la mise en œuvre Multi-Threading de Java .

    Un AsyncTask est utilisé pour effectuer un calcul d'arrière-plan et publier le résultat sur le thread UI (avec les mises à jour de progression facultatives). Comme vous ne vous souciez pas de l'interface utilisateur, un Handler ou un Thread semble plus approprié.

    Vous pouvez générer un arrière-plan. Thread et transmettre des messages à votre thread principal en utilisant la méthode de post Gestionnaire.

    À mon avis, les threads ne sont pas le moyen le plus efficace de faire des connexions socket, mais ils fournissent le plus de fonctionnalités en termes d'exécution de threads. Je dis que, grâce à l'expérience, l'exécution de threads depuis longtemps entraîne une chaleur et une intensité de ressources des appareils. Même un simple while(true) va chauffer un téléphone en quelques minutes. Si vous dites que l'interaction UI n'est pas importante, peut-être un AsyncTask est bon car ils sont conçus pour des processus à long terme. C'est mon opinion sur ce sujet.

    METTRE À JOUR

    Veuillez ignorer ma réponse ci-dessus! J'ai répondu à cette question en 2011 lorsque j'avais beaucoup moins d'expérience dans Android que moi. Ma réponse ci-dessus est trompeuse et est considérée comme incorrecte. Je le laisse là-bas parce que beaucoup de gens ont commenté cela en dessous de me corriger, et j'ai appris ma leçon.

    Il y a bien d'autres 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 Thread Java régulier; Cependant, vous devriez vraiment faire attention à la façon dont vous l'implémentez car il est faux peut être très processeur (le symptôme le plus remarquable peut être le réchauffement de votre appareil). AsyncTask s est assez idéal pour la plupart des tâches que vous souhaitez exécuter en arrière-plan (les exemples courants sont les E / S de disque, les appels réseau et les appels de base de données). Cependant, AsyncTask s ne doit pas être utilisé pour des processus particulièrement longs qui peuvent devoir continuer après que l'utilisateur a fermé votre application ou mettre son appareil en veille. Je dirais pour la plupart des cas, tout ce qui n'appartient pas au fil UI, peut être pris en charge dans un AsyncTask .

    Fils

    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 directement mettre à jour l'interface utilisateur à partir d'un processus en arrière-plan. Si vous devez mettre à jour l'interface utilisateur 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 ceci ou la classe "AsyncTasks"

    Handler

    La classe "Handler" peut mettre à jour l'interface utilisateur. Une poignée fournit des méthodes pour recevoir des messages et pour exécuter. Pour utiliser un gestionnaire, vous devez la sous-classe et remplacer handleMessage () pour traiter les messages. Pour traiter les runables, vous pouvez utiliser la méthode post (); Vous n'avez besoin que d'une instance de gestionnaire dans votre activité. Vous pouvez publier des messages via la méthode sendMessage (message msg) ou sendEmptyMessage.

    AsyncTask

    Si vous avez une activité qui doit télécharger du contenu ou effectuer des opérations qui peuvent être effectuées en arrière-plan, AsyncTask vous permet de maintenir une interface utilisateur adaptée et de publier des progrès pour ces opérations à l'utilisateur.

    Pour plus d'informations, vous pouvez consulter les liens suivants.

    http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/

    http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask

    La tâche asynchimique est conçue pour effectuer une opération de plus de quelques secondes à fond en arrière-plan (non recommandé pour les mégaoctets de téléchargement de fichiers à partir du serveur ou pour une tâche intensive de la CPU, par exemple les opérations IO du fichier). Si vous voulez une longue opération, il est fortement conseillé d'utiliser les threads natifs de Java. Java vous propose différentes classes liées au fil pour faire ce dont vous avez besoin. Utilisez les gestionnaires pour mettre à jour le thread UI.

    Permettez-moi d'essayer de répondre à la question ici avec un exemple 🙂 – MyImageSearch [Veuillez référencer l'image ici de l'écran d'activité principal – contenant un texte d'édition / un bouton de recherche / une vue de grille]

    MyImageSearch

    Description de MyImageSearchUne fois que l'utilisateur entre les détails sur le champ de texte d'édition et clique sur le bouton de recherche, nous chercherons des images sur Internet via les services Web fournis par flickr (il suffit de vous inscrire pour obtenir un jeton clé / secret) – pour la recherche, nous envoyons une demande HTTP et GET JSON Data en réponse contenant les URL des images individuelles que nous utiliserons ensuite pour charger la vue de la grille.

    Ma mise en œuvreDans l'activité principale, je définirai une classe interne qui étend le AsyncTask pour envoyer la requête HTTP dans la méthode doInBackGround et récupérer la réponse JSON et mettre à jour mon ArrayList local de FlickrItems que je vais utiliser pour mettre à jour mon GridView via FlickrAdapter (Étend le BaseAdapter) et appelle l'adaptateur.notifyDataSetChanged () dans onPostExecute () d'AsyncTask pour recharger la vue de la grille. Notez que ici, la requête HTTP est un appel de blocage à cause de laquelle 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 la carte SD. La grille que je vais gonfler dans FlickrAdapter contient dans ma mise en œuvre 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 disposons des données JSON pour récupérer des images individuelles, nous pouvons implémenter la logique d'obtenir les images en arrière plan via Handlers ou Threads ou AsyncTask. Nous devrions noter ici que, puisque mes images qu'une fois téléchargées doivent être affichées sur le thread UI / principal, nous ne pouvons pas simplement utiliser les threads tel qu'il est, car ils n'ont pas accès au contexte. Dans le FlickrAdapter, les choix que je pourrais penser:

    • Choix 1: Créez un LooperThread [extends thread] – et continuez de télécharger des images séquentiellement dans un thread en maintenant ce thread ouvert [looper.loop ()]
    • Choix 2: Utiliser un pool de fil et publier l'exécution via myHandler qui contient une référence à mon ImageView, mais comme les vues en Grid View sont recyclées, le problème peut se produire lorsque l'image à l'index 4 est affichée à l'index 9 [télécharger peut-être Prendre plus de temps]
    • Choix 3 [J'ai utilisé ceci]: Faites usage d'un pool de threads et envoyez un message à myHandler, qui contient des données liées à l'index ImageView et ImageView lui-même, alors, pendant que handleMessage (), nous allons mettre à jour l'ImageView uniquement si currentIndex correspond à l'index de L'image que nous avons essayé de télécharger.
    • Choix 4: Utilisez AsyncTask pour télécharger les images en arrière-plan, mais ici je n'aurai pas accès au nombre de threads que je veux dans le groupe de threads et il varie selon la version Android différente, mais dans le choix 3, je peux prendre une décision consciente De la taille du groupe de threads en fonction de la configuration du périphérique utilisée.

    Voici le code source:

     public class MainActivity extends ActionBarActivity { GridView imageGridView; ArrayList<FlickrItem> items = new ArrayList<FlickrItem>(); FlickrAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageGridView = (GridView) findViewById(R.id.gridView1); adapter = new FlickrAdapter(this, items); imageGridView.setAdapter(adapter); } // To avoid a memory leak on configuration change making it a inner class class FlickrDownloader extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { FlickrGetter getter = new FlickrGetter(); ArrayList<FlickrItem> newItems = getter.fetchItems(); // clear the existing array items.clear(); // add the new items to the array items.addAll(newItems); // is this correct ? - Wrong rebuilding the list view and should not be done in background //adapter.notifyDataSetChanged(); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); adapter.notifyDataSetChanged(); } } public void search(View view) { // get the flickr data FlickrDownloader downloader = new FlickrDownloader(); downloader.execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } 

    J'espère que ma réponse sera utile pour comprendre certains des détails plus fins.

     public class RequestHandler { public String sendPostRequest(String requestURL, HashMap<String, String> postDataParams) { URL url; StringBuilder sb = new StringBuilder(); try { url = new URL(requestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(15000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setDoInput(true); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8")); writer.write(getPostDataString(postDataParams)); writer.flush(); writer.close(); os.close(); int responseCode = conn.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); sb = new StringBuilder(); String response; while ((response = br.readLine()) != null){ sb.append(response); } } } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for (Map.Entry<String, String> entry : params.entrySet()) { if (first) first = false; else result.append("&"); result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); } return result.toString(); } } 

    Handler – est un moyen de communication entre les threads. Dans Android, il est surtout utilisé pour communiquer avec le thread principal en créant et en envoyant des messages via un gestionnaire

    AsyncTask – est utilisé pour exécuter des applications de longue durée dans un thread en arrière-plan. Avec n AsyncTask vous obtenez, vous pouvez effectuer l'opération dans un thread en arrière-plan et obtenir le résultat dans le thread principal de l'application.

    Thread – est un processus léger, pour atteindre la concurrence et l'utilisation maximale du processeur. Dans Android, vous pouvez utiliser le thread pour effectuer des activités qui ne touchent pas l'interface utilisateur de l'application

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.