Quel est l'objectif de Looper et comment l'utiliser?

454

Je suis nouveau sur Android. Je veux savoir ce que fait la Looperclasse 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 Looperet aussi en donnant un exemple simple si possible?

Khawar Raza
la source
7
Je viens de trouver une explication extrêmement approfondie et claire de Looper et de son utilisation sur Safari Books Online. Malheureusement, je soupçonne l'accès s'il est gratuit pour une durée limitée. safaribooksonline.com/library/view/efficient-android-threading/…
Joe Lapp
1
Les articles et les pages de référence Android nécessitent que vous ayez et compreniez un article précédent, avant de pouvoir saisir l'article actuel. Je vous suggère de lire les articles Activité et Service dans les guides Api, puis de lire Handler et Looper. Cela aide également si vous comprenez ce qu'est un thread (pas un thread android, mais un thread en général ... par exemple POSIX).
FutureSci
1
J'ai trouvé cet article utile: codetheory.in/…
Herman

Réponses:

396

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 la loop()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.

class LooperThread extends Thread {
      public Handler mHandler;

      @Override
      public void run() {
          Looper.prepare();

          mHandler = new Handler() {
              @Override
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }
Dharmendra
la source
17
Une AsyncTask est meilleure à cet effet et moins complexe car elle encapsule toute la gestion des threads.
Fernando Gallego
4
Devrait avoir des annotations @Override avant les méthodes run () et handleMessage ()
Andrew Mackenzie
5
La documentation indique que vous devez appeler looper.quit. Dans votre code ci-dessus, Looper.loop se bloquera indéfiniment.
AndroidDev
2
Comment quitter une boucle. Je veux dire où inclure Looper.quit () dans l'exemple de code ci-dessus?
Seenu69
6
Je pense qu'il serait préférable d'utiliser HandlerThread qui est une classe pratique pour un thread avec un looper.
Nimrod Dayan du
287

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.

public class HelloRunnable implements Runnable {
    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}

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.

public final class ActivityThread {
    ...
    public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();
        Looper.loop();
        ...
    }
}

et Looper.loop()boucle de méthode à l'infini et retirer un message et traiter un à la fois:

public static void loop() {
    ...
    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }
        ...
        msg.target.dispatchMessage(msg);
        ...
    }
}

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
26
C'est la seule réponse qui explique réellement pourquoi la classe Looper serait utilisée. Je ne sais pas pourquoi ce n'est pas la première réponse, les trois réponses les mieux notées n'expliquent rien.
Andrew Koster
4
@AK. C'est pourquoi j'ai ajouté cette réponse même si cela semblait trop tard. Je suis content que ma réponse vous ait aidé! :)
김준호
1
@ Hey-men-whatsup Oui
김준호
1
Avant de lire ceci, je me disais "Looper ???" et maintenant "Oh ouais, discutons-en". Merci mec, bonne réponse :)
umerk44
Question rapide. Vous avez déclaré que dans le fil principal après avoir extrait tous les éléments de l'interface utilisateur, il est mis en veille. Mais disons que l'utilisateur interagit avec un bouton à l'écran, ce bouton n'est-il pas même mis dans une file d'attente principale, alors un objet le distribuera à l'activité correcte, puis le thread principal de cette activité est réveillé et il s'exécutera le code pour dans le rappel de ce bouton, cliquez sur?
CapturedTree
75

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:

class SampleLooper extends Thread {
@Override
public void run() {
  try {
    // preparing a looper on current thread     
    // the current thread is being detected implicitly
    Looper.prepare();

    // now, the handler will automatically bind to the
    // Looper that is attached to the current thread
    // You don't need to specify the Looper explicitly
    handler = new Handler();

    // After the following line the thread will start
    // running the message loop and will not normally
    // exit the loop unless a problem happens or you
    // quit() the looper (see below)
    Looper.loop();
  } catch (Throwable t) {
    Log.e(TAG, "halted due to an error", t);
  } 
}
}

Maintenant, nous pouvons utiliser le gestionnaire dans certains autres threads (par exemple le thread ui) pour publier la tâche sur Looper à exécuter.

handler.post(new Runnable()
{
public void run() {
//This will be executed on thread using Looper.
    }
});

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.

user2834274
la source
cela ne verrouillera aucun processus d'interface utilisateur, est-ce vrai?
gumuruh
4
Merci d'avoir inclus un échantillon sur la façon de publier des "emplois" dans la file d'attente
Peter Lillevold
Cela n'explique pas pourquoi on utiliserait cette classe, seulement comment.
Andrew Koster
33

Android Looperest un wrapper pour attacher MessageQueueà Threadet il gère le traitement des files d' attente. Il semble très cryptique dans la documentation Android et nous pouvons souvent rencontrer Looperdes 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 Loopercycle de vie, comment l'utiliser et son utilisation LooperdansHandler

entrez la description de l'image ici

Looper = Thread + MessageQueue

user542954
la source
3
Cela n'explique pas pourquoi on utiliserait cette classe, seulement comment.
Andrew Koster
14

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

ahmadalibaloch
la source
7

Un Looper a un synchronized MessageQueuequi est utilisé pour traiter les messages placés dans la file d'attente.

Il implémente un Threadmodèle de stockage spécifique.

Un seul Looperpar Thread. Les méthodes clés incluent prepare(), loop()et quit().

prepare()initialise le courant en Threadtant que Looper. prepare()est une staticméthode qui utilise la ThreadLocalclasse comme indiqué ci-dessous.

   public static void prepare(){
       ...
       sThreadLocal.set
       (new Looper());
   }
  1. prepare() doit être appelé explicitement avant d'exécuter la boucle d'événements.
  2. 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, la loop()méthode envoie le message à son gestionnaire cible
  3. quit()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écial

Looperpeut être programmé en Threadplusieurs étapes

  1. Étendre Thread

  2. Appelez Looper.prepare()pour initialiser Thread en tant queLooper

  3. Créez un ou plusieurs Handler(s) pour traiter les messages entrants

  4. Appelez Looper.loop()pour traiter les messages jusqu'à ce que la boucle soit avertie quit().
Théo
la source
5

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 Threaden boucle de message. Les principales méthodes Loopersont:

void prepare ()

Initialisez le thread actuel en tant que zone répétée. Cela vous donne la possibilité de créer des gestionnaires qui référencent ensuite ce looper, avant de démarrer réellement la boucle. Assurez-vous d'appeler loop () après avoir appelé cette méthode, et terminez-la en appelant quit ().

void loop ()

Exécutez la file d'attente de messages dans ce fil. Assurez-vous d'appeler quit () pour terminer la boucle.

void quit()

Quitte le looper.

Force la méthode loop () à se terminer sans traiter plus de messages dans la file d'attente de messages.

Cet article de Mindorks de Janishar explique les concepts de base de manière agréable.

entrez la description de l'image ici

Looperest associé à un fil. Si vous avez besoin Loopersur le thread d'interface utilisateur, Looper.getMainLooper()retournera le thread associé.

Vous devez Looperêtre associé à un gestionnaire .

Looper,, Handleret HandlerThreadsont 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.

post (Runnable r)

Provoque l'ajout de Runnable r à la file d'attente de messages. L'exécutable sera exécuté sur le thread auquel ce gestionnaire est attaché.

boolean sendMessage (Message msg)

Pousse un message à la fin de la file d'attente de messages après tous les messages en attente avant l'heure actuelle. Il sera reçu dans handleMessage (Message), dans le thread attaché à ce gestionnaire.

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 Runnabletâ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, HandlerThreadest utile. Vous pouvez obtenir un Looperobjet de HandlerThreadet créer un Handlersur HandlerThreadau lieu du thread principal.

Le code HandlerThread sera comme ceci:

@Override
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

Référez-vous au message ci-dessous pour un exemple de code:

Android: Toast dans un fil

Ravindra babu
la source
5

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: entrez la description de l'image ici

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.

Lorsqu'une application est lancée, le système crée un thread d'exécution pour l'application, appelé "main". Ce thread est très important car il est chargé de répartir les événements vers les widgets d'interface utilisateur appropriés, y compris les événements de dessin.

entrez la description de l'image ici

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?

La réponse est Looper Class : Looper est une classe qui est utilisée pour maintenir un thread en vie et gérer une file d'attente de messages pour exécuter des tâches sur ce thread.

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 ().

Le but de Looper est de maintenir un thread en vie et d'attendre le prochain cycle de l' Messageobjet d' entrée pour effectuer un calcul qui, sinon, sera détruit après le premier cycle d'exécution.

Si vous souhaitez approfondir la façon dont Looper gère Messagela file d'attente des objets, vous pouvez consulter le code source de Looperclass:

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/Looper.java

Voici un exemple de la façon dont vous pouvez créer une classe Looper Threadet communiquer avec elle en ActivityutilisantLocalBroadcast

class LooperThread : Thread() {

    // sendMessage success result on UI
    private fun sendServerResult(result: String) {
        val resultIntent = Intent(ServerService.ACTION)
        resultIntent.putExtra(ServerService.RESULT_CODE, Activity.RESULT_OK)
        resultIntent.putExtra(ServerService.RESULT_VALUE, result)
        LocalBroadcastManager.getInstance(AppController.getAppController()).sendBroadcast(resultIntent)
    }

    override fun run() {
        val looperIsNotPreparedInCurrentThread = Looper.myLooper() == null

        // Prepare Looper if not already prepared
        if (looperIsNotPreparedInCurrentThread) {
            Looper.prepare()
        }

        // Create a handler to handle messaged from Activity
        handler = Handler(Handler.Callback { message ->
            // Messages sent to Looper thread will be visible here
            Log.e(TAG, "Received Message" + message.data.toString())

            //message from Activity
            val result = message.data.getString(MainActivity.BUNDLE_KEY)

            // Send Result Back to activity
            sendServerResult(result)
            true
        })

        // Keep on looping till new messages arrive
        if (looperIsNotPreparedInCurrentThread) {
            Looper.loop()
        }
    }

    //Create and send a new  message to looper
    fun sendMessage(messageToSend: String) {
        //Create and post a new message to handler
        handler!!.sendMessage(createMessage(messageToSend))
    }


    // Bundle Data in message object
    private fun createMessage(messageToSend: String): Message {
        val message = Message()
        val bundle = Bundle()
        bundle.putString(MainActivity.BUNDLE_KEY, messageToSend)
        message.data = bundle
        return message
    }

    companion object {
        var handler: Handler? = null // in Android Handler should be static or leaks might occur
        private val TAG = javaClass.simpleName

    }
}

Utilisation :

 class MainActivity : AppCompatActivity() {

    private var looperThread: LooperThread? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // start looper thread
        startLooperThread()

        // Send messages to Looper Thread
        sendMessage.setOnClickListener {

            // send random messages to looper thread
            val messageToSend = "" + Math.random()

            // post message
            looperThread!!.sendMessage(messageToSend)

        }   
    }

    override fun onResume() {
        super.onResume()

        //Register to Server Service callback
        val filterServer = IntentFilter(ServerService.ACTION)
        LocalBroadcastManager.getInstance(this).registerReceiver(serverReceiver, filterServer)

    }

    override fun onPause() {
        super.onPause()

        //Stop Server service callbacks
     LocalBroadcastManager.getInstance(this).unregisterReceiver(serverReceiver)
    }


    // Define the callback for what to do when data is received
    private val serverReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val resultCode = intent.getIntExtra(ServerService.RESULT_CODE, Activity.RESULT_CANCELED)
            if (resultCode == Activity.RESULT_OK) {
                val resultValue = intent.getStringExtra(ServerService.RESULT_VALUE)
                Log.e(MainActivity.TAG, "Server result : $resultValue")

                serverOutput.text =
                        (serverOutput.text.toString()
                                + "\n"
                                + "Received : " + resultValue)

                serverScrollView.post( { serverScrollView.fullScroll(View.FOCUS_DOWN) })
            }
        }
    }

    private fun startLooperThread() {

        // create and start a new LooperThread
        looperThread = LooperThread()
        looperThread!!.name = "Main Looper Thread"
        looperThread!!.start()

    }

    companion object {
        val BUNDLE_KEY = "handlerMsgBundle"
        private val TAG = javaClass.simpleName
    }
}

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 ThreadPoolExecutorn'autoriseront que jusqu'à 5 tâches asynchrones .

  • IntentServicessont également conçus pour effectuer une tâche en arrière-plan pendant une durée un peu plus longue et vous pouvez utiliser LocalBroadcastpour communiquer avec Activity. 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 comme while(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.

Hitesh Sahu
la source
4

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:

HandlerThread thread = new HandlerThread(threadName);
thread.start();
Looper looper = thread.getLooper();
Handler myHandler = new Handler(looper);

et pour une mise en œuvre complète

TacB0sS
la source
3

La gestion de plusieurs éléments vers le bas ou de téléchargement dans un service est un meilleur exemple.

Handleret AsnycTasksont 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 Loopergè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).

Thorsten
la source
1

Qu'est-ce que Looper?

DE DOCS

Looper

LooperClasse utilisée pour exécuter une boucle de message pour a thread. Les threads par défaut n'ont pas de boucle de message qui leur est associée; pour en créer un, appelez prepare()le thread qui doit exécuter la boucle, puis loop()demandez-lui de traiter les messages jusqu'à ce que la boucle soit arrêtée.

  • A Looperest une boucle de gestion des messages:
  • Un caractère important de Looper est qu'il est associé au thread dans lequel le Looper est créé
  • La classe Looper gère un 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éé.
  • Le Looperest nommé ainsi car il implémente la boucle - prend la tâche suivante, l'exécute, puis prend la suivante et ainsi de suite. Le Handlers'appelle un gestionnaire parce que quelqu'un ne pourrait pas inventer un meilleur nom
  • Android Looperest 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.

Comment ça fonctionne?

entrez la description de l'image ici

Création d'une zone répétée

Un thread obtient un Looperet MessageQueueen appelant Looper.prepare()après son exécution. Looper.prepare()identifie le thread appelant, crée un Looper et un MessageQueueobjet et associe le thread

EXEMPLE DE CODE

class MyLooperThread extends Thread {

      public Handler mHandler; 

      public void run() { 

          // preparing a looper on current thread  
          Looper.prepare();

          mHandler = new Handler() { 
              public void handleMessage(Message msg) { 
                 // process incoming messages here
                 // this will run in non-ui/background thread
              } 
          }; 

          Looper.loop();
      } 
  }

Pour plus d'informations, consultez le post ci-dessous

Nilesh Rathod
la source
excellent, j'ai compris la mécanique. merci
Serg Burlaka