Je suis nouveau sur Android. Je veux savoir ce que fait la Looper
classe et comment l'utiliser. J'ai lu la documentation de la classe Android Looper mais je n'arrive pas à la comprendre complètement. Je l'ai vu dans de nombreux endroits, mais je n'arrive pas à comprendre son objectif. Quelqu'un peut-il m'aider en définissant le but de Looper
et aussi en donnant un exemple simple si possible?
android
multithreading
android-looper
Khawar Raza
la source
la source
Réponses:
Qu'est-ce que Looper?
Looper est une classe qui est utilisée pour exécuter les messages (Runnables) dans une file d'attente. Les threads normaux n'ont pas une telle file d'attente, par exemple un thread simple n'a pas de file d'attente. Il s'exécute une fois et une fois l'exécution de la méthode terminée, le thread n'exécutera pas un autre message (Runnable).
Où pouvons-nous utiliser la classe Looper?
Si quelqu'un veut exécuter plusieurs messages (Runnables), il doit utiliser la classe Looper qui est responsable de la création d'une file d'attente dans le thread. Par exemple, lors de l'écriture d'une application qui télécharge des fichiers depuis Internet, nous pouvons utiliser la classe Looper pour placer les fichiers à télécharger dans la file d'attente.
Comment ça fonctionne?
Il existe une
prepare()
méthode pour préparer le Looper. Ensuite, vous pouvez utiliser laloop()
méthode pour créer une boucle de message dans le thread actuel et maintenant votre Looper est prêt à exécuter les requêtes dans la file d'attente jusqu'à ce que vous quittiez la boucle.Voici le code par lequel vous pouvez préparer le Looper.
la source
Vous pouvez mieux comprendre ce qu'est Looper dans le contexte du framework GUI. Looper est fait pour faire 2 choses.
1) Looper transforme un thread normal , qui se termine lorsque sa méthode run () revient, en quelque chose exécuté en continu jusqu'à ce que l'application Android soit en cours d'exécution , ce qui est nécessaire dans le cadre de l'interface graphique (techniquement, il se termine toujours lorsque la méthode run () revient. Mais permettez-moi de clarifier ce que je veux dire ci-dessous).
2) Looper fournit une file d'attente où les travaux à effectuer sont mis en file d'attente, ce qui est également nécessaire dans le cadre de l'interface graphique.
Comme vous le savez peut-être, lorsqu'une application est lancée, le système crée un thread d'exécution pour l'application, appelé «principal», et les applications Android s'exécutent normalement entièrement sur un seul thread par défaut le «thread principal». Mais le fil principal n'est pas un fil spécial secret . C'est juste un thread normal similaire aux threads que vous créez avec du
new Thread()
code, ce qui signifie qu'il se termine lorsque sa méthode run () revient! Pensez à l'exemple ci-dessous.Maintenant, appliquons ce principe simple aux applications Android. Que se passerait-il si une application Android s'exécute sur un thread normal? Un thread appelé "principal" ou "UI" ou quoi que ce soit qui démarre votre application, et dessine toute l'interface utilisateur. Ainsi, le premier écran s'affiche pour les utilisateurs. Et maintenant? Le fil principal se termine? Non, ça ne devrait pas. Cela devrait attendre que les utilisateurs fassent quelque chose, non? Mais comment pouvons-nous atteindre ce comportement? Eh bien, nous pouvons essayer avec
Object.wait()
ouThread.sleep()
. Par exemple, le thread principal termine son travail initial pour afficher le premier écran et se met en veille. Il se réveille, ce qui signifie interrompu, lorsqu'un nouveau travail à faire est récupéré. Jusqu'ici tout va bien, mais pour le moment, nous avons besoin d'une structure de données de type file d'attente pour contenir plusieurs travaux. Pensez à un cas où un utilisateur touche l'écran en série et qu'une tâche prend plus de temps à se terminer. Donc, nous devons avoir une structure de données pour conserver les tâches à effectuer selon le principe du premier entré, premier sorti. En outre, vous pouvez imaginer que l'implémentation de threads toujours en cours d'exécution et de processus de travail à l'arrivée à l'aide d'une interruption n'est pas facile et conduit à un code complexe et souvent impossible à maintenir. Nous préférons créer un nouveau mécanisme à cet effet, et c'est ce que Looper est tout au sujet . Le document officiel de la classe Looperdit, "Les threads par défaut n'ont pas de boucle de message qui leur est associée", et Looper est une classe "utilisée pour exécuter une boucle de message pour un thread". Vous pouvez maintenant comprendre ce que cela signifie.Pour rendre les choses plus claires, vérifions le code où le thread principal est transformé. Tout se passe dans la classe ActivityThread . Dans sa méthode main (), vous pouvez trouver ci-dessous le code, qui transforme un thread principal normal en quelque chose dont nous avons besoin.
et
Looper.loop()
boucle de méthode à l'infini et retirer un message et traiter un à la fois:Donc, fondamentalement, Looper est une classe conçue pour résoudre un problème qui se produit dans le cadre de l'interface graphique. Mais ce genre de besoins peut également se produire dans d'autres situations. En fait, c'est un modèle assez célèbre pour l'application multi-threads, et vous pouvez en apprendre plus à ce sujet dans " Programmation simultanée en Java " par Doug Lea (en particulier, le chapitre 4.1.4 "Worker Threads" serait utile). En outre, vous pouvez imaginer que ce type de mécanisme n'est pas unique dans le cadre Android, mais tous les cadres GUI peuvent avoir besoin de quelque chose de similaire. Vous pouvez trouver presque le même mécanisme dans le framework Java Swing.
la source
Looper permet d'exécuter les tâches séquentiellement sur un seul thread. Et le gestionnaire définit les tâches que nous devons exécuter. C'est un scénario typique que j'essaie d'illustrer dans cet exemple:
Maintenant, nous pouvons utiliser le gestionnaire dans certains autres threads (par exemple le thread ui) pour publier la tâche sur Looper à exécuter.
Sur le thread d'interface utilisateur, nous avons un Looper implicite qui nous permet de gérer les messages sur le thread d'interface utilisateur.
la source
Android
Looper
est un wrapper pour attacherMessageQueue
àThread
et il gère le traitement des files d' attente. Il semble très cryptique dans la documentation Android et nous pouvons souvent rencontrerLooper
des problèmes d'accès à l'interface utilisateur. Si nous ne comprenons pas les bases, cela devient très difficile à gérer.Voici un article qui explique le
Looper
cycle de vie, comment l'utiliser et son utilisationLooper
dansHandler
Looper = Thread + MessageQueue
la source
Définition de Looper & Handler:
Looper est une classe qui transforme un thread en un thread de pipeline et le gestionnaire vous donne un mécanisme pour y pousser des tâches à partir de tout autre thread.
Détails:
Un thread PipeLine est donc un thread qui peut accepter plus de tâches provenant d'autres threads via un gestionnaire.
Le Looper est nommé ainsi parce qu'il implémente la boucle - prend la tâche suivante, l'exécute, puis prend la suivante et ainsi de suite. Le gestionnaire est appelé gestionnaire car il est utilisé pour gérer ou accepter la tâche suivante à chaque fois à partir de tout autre thread et passer à Looper (Thread ou PipeLine Thread).
Exemple:
Un exemple parfait de Looper and Handler ou PipeLine Thread consiste à télécharger plusieurs images ou à les télécharger sur un serveur (Http) une par une dans un seul thread au lieu de démarrer un nouveau thread pour chaque appel réseau en arrière-plan.
En savoir plus ici sur Looper and Handler et la définition du thread de pipeline:
Android Guts: introduction aux boucles et aux gestionnaires
la source
Un Looper a un
synchronized
MessageQueue
qui est utilisé pour traiter les messages placés dans la file d'attente.Il implémente un
Thread
modèle de stockage spécifique.Un seul
Looper
parThread
. Les méthodes clés incluentprepare()
,loop()
etquit()
.prepare()
initialise le courant enThread
tant queLooper
.prepare()
est unestatic
méthode qui utilise laThreadLocal
classe comme indiqué ci-dessous.prepare()
doit être appelé explicitement avant d'exécuter la boucle d'événements.loop()
exécute la boucle d'événements qui attend que les messages arrivent dans la file de messages d'un thread spécifique. Une fois le prochain message reçu, laloop()
méthode envoie le message à son gestionnaire ciblequit()
ferme la boucle d'événements. Il ne met pas fin à la boucle, mais à la place, il met en file d'attente un message spécialLooper
peut être programmé enThread
plusieurs étapesÉtendre
Thread
Appelez
Looper.prepare()
pour initialiser Thread en tant queLooper
Créez un ou plusieurs
Handler
(s) pour traiter les messages entrantsLooper.loop()
pour traiter les messages jusqu'à ce que la boucle soit avertiequit()
.la source
La durée de vie du thread java est terminée une fois la
run()
méthode terminée . Le même thread ne peut pas être redémarré.Le boucleur transforme la normale
Thread
en boucle de message. Les principales méthodesLooper
sont:Cet article de Mindorks de Janishar explique les concepts de base de manière agréable.
Looper
est associé à un fil. Si vous avez besoinLooper
sur le thread d'interface utilisateur,Looper.getMainLooper()
retournera le thread associé.Vous devez
Looper
être associé à un gestionnaire .Looper
,,Handler
etHandlerThread
sont la manière d'Android de résoudre les problèmes de programmation asynchrone.Une fois que vous avez
Handler
, vous pouvez appeler les API ci-dessous.HandlerThread est une classe pratique pour démarrer un nouveau thread qui a un looper. Le looper peut ensuite être utilisé pour créer des classes de gestionnaires
Dans certains scénarios, vous ne pouvez pas exécuter de
Runnable
tâches sur le thread d'interface utilisateur. Ex: opérations réseau: envoyer un message sur un socket, ouvrir une URL et obtenir du contenu en lisantInputStream
Dans ces cas,
HandlerThread
est utile. Vous pouvez obtenir unLooper
objet deHandlerThread
et créer unHandler
surHandlerThread
au lieu du thread principal.Le code HandlerThread sera comme ceci:
Référez-vous au message ci-dessous pour un exemple de code:
Android: Toast dans un fil
la source
Comprendre les threads du boucleur
Un java Thread une unité d'exécution qui a été conçue pour effectuer une tâche dans sa méthode run () et se terminer après cela:
Mais dans Android, il existe de nombreux cas d'utilisation où nous devons garder un fil vivant et attendre par exemple les entrées / événements de l'utilisateur. Fil d'interface aka
Main Thread
.Le thread principal dans Android est un thread Java qui est démarré pour la première fois par JVM au lancement d'une application et continue de fonctionner jusqu'à ce que l'utilisateur choisisse de le fermer ou rencontre une exception non gérée.
Maintenant, le point à noter ici est que le thread principal est le thread Java, mais il continue d'écouter les événements utilisateur et de dessiner des images à 60 ips à l'écran et il ne mourra toujours pas après chaque cycle. comment est-il ainsi?
Les threads par défaut n'ont pas de boucle de message qui leur est associée, mais vous pouvez en affecter une en appelant Looper.prepare () dans la méthode d'exécution, puis appelez Looper.loop ().
Si vous souhaitez approfondir la façon dont Looper gère
Message
la file d'attente des objets, vous pouvez consulter le code source deLooperclass
:Voici un exemple de la façon dont vous pouvez créer une classe
Looper Thread
et communiquer avec elle enActivity
utilisantLocalBroadcast
Utilisation :
Pouvons-nous utiliser la tâche Async ou les services d'intention à la place?
Les tâches asynchrones sont conçues pour effectuer une courte opération en arrière-plan et donner des progrès et des résultats sur le thread d'interface utilisateur. Les tâches asynchrones ont des limites comme vous ne pouvez pas créer plus de 128 tâches asynchrones et
ThreadPoolExecutor
n'autoriseront que jusqu'à 5 tâches asynchrones .IntentServices
sont également conçus pour effectuer une tâche en arrière-plan pendant une durée un peu plus longue et vous pouvez utiliserLocalBroadcast
pour communiquer avecActivity
. Mais les services sont détruits après l'exécution de la tâche. Si vous voulez le faire fonctionner pendant longtemps, vous devez faire des conneries commewhile(true){...}
.Autres cas d'utilisation significatifs pour le Looper Thread:
Utilisé pour la communication de socket bidirectionnelle où le serveur continue d'écouter le socket client et de réécrire l'accusé de réception
Traitement bitmap en arrière-plan. Passez l'url de l'image au thread Looper et il appliquera des effets de filtre et la stockera dans un emplacement temporaire, puis diffusera le chemin temporaire de l'image.
la source
Cette réponse n'a rien à voir avec la question, mais l'utilisation de looper et la façon dont les gens ont créé le gestionnaire et le looper dans TOUTES les réponses ici sont de mauvaises pratiques (certaines explications sont cependant correctes), je dois poster ceci:
et pour une mise en œuvre complète
la source
La gestion de plusieurs éléments vers le bas ou de téléchargement dans un service est un meilleur exemple.
Handler
etAsnycTask
sont souvent utilisés pour propager des événements / messages entre l' interface utilisateur (thread) et un thread de travail ou pour retarder des actions. Ils sont donc plus liés à l'interface utilisateur.A
Looper
gère les tâches ( Runnables, Futures ) dans une file d'attente liée aux threads en arrière-plan - même sans interaction de l'utilisateur ou interface utilisateur affichée (l'application télécharge un fichier en arrière-plan pendant un appel).la source
DE DOCS
Looper
Looper
Classe utilisée pour exécuter une boucle de message pour athread
. Les threads par défaut n'ont pas de boucle de message qui leur est associée; pour en créer un, appelezprepare()
le thread qui doit exécuter la boucle, puisloop()
demandez-lui de traiter les messages jusqu'à ce que la boucle soit arrêtée.Looper
est une boucle de gestion des messages:MessageQueue
, qui contient une liste de messages. Un caractère important de Looper est qu'il est associé au thread dans lequel le Looper est créé.Looper
est nommé ainsi car il implémente la boucle - prend la tâche suivante, l'exécute, puis prend la suivante et ainsi de suite. LeHandler
s'appelle un gestionnaire parce que quelqu'un ne pourrait pas inventer un meilleur nomLooper
est une classe Java dans l'interface utilisateur Android qui, avec la classe Handler, traite les événements d'interface utilisateur tels que les clics sur les boutons, les rafraîchissements d'écran et les commutateurs d'orientation.Un thread obtient un
Looper
etMessageQueue
en appelantLooper.prepare()
après son exécution.Looper.prepare()
identifie le thread appelant, crée un Looper et unMessageQueue
objet et associe le threadEXEMPLE DE CODE
Pour plus d'informations, consultez le post ci-dessous
la source