Réponse courte: elles fonctionnent toutes sur le même thread. Si instancié à partir d'une Activity
du cycle de vie de rappel, ils sont tous exécutés sur le main thread d'INTERFACE utilisateur.
Réponse longue:
Un thread peut avoir un Looper
, qui contient un MessageQueue
. Pour utiliser cette fonction, vous devez créer un Looper
sur le thread en cours en appelant le (statique) Looper.prepare()
, puis de commencer la boucle en appelant le (la aussi statique) Looper.loop()
. Ces sont statiques, car il est supposé être un Looper
par thread.
L'appel à l' loop()
n'a en général pas de retour pour un certain temps, mais continue à prendre de messages ("tâches", "commandes" ou ce que vous voulez l'appeler) de l' MessageQueue
et les gère individuellement (par exemple, en appelant au retour d'un Runnable
contenues dans le message). Quand il y a pas de messages dans la file d'attente, le thread se bloque jusqu'à ce qu'il y a de nouveaux messages. Pour arrêter un Looper
, vous appelez quit()
"(qu'il n'a probablement pas arrêter immédiatement la boucle, mais établit plutôt un indicateur privé qui est vérifié périodiquement à partir de la boucle, la signalisation de l'il à l'arrêt).
Cependant, vous ne pouvez pas ajouter des messages à la file d'attente directement. Au lieu de cela, vous vous inscrivez à un MessageQueue.IdleHandler
à attendre une queueIdle()
rappel, dans lesquels vous pouvez décider si vous voulez quelque chose ou pas. Tous les gestionnaires sont appelés à tour de rôle. (Donc la "file d'attente" n'est pas vraiment une file d'attente, mais plutôt une collection de rappels d'être appelé régulièrement.)
Remarque concernant le paragraphe précédent: Ce que je fait deviner. Je ne pouvais pas trouver toute la documentation sur ce point, mais il aurait du sens.
mise à jour: voir ahcox' commentaire et de sa réponse.
Parce que c'est beaucoup de travail, le cadre fournit l' Handler
classe pour simplifier les choses. Lorsque vous créez un Handler
de l'instance, il est (par défaut) lié à l' Looper
déjà attaché au thread courant. (L' Handler
sait ce qu' Looper
pour attacher parce que nous avons appelé prepare()
précédemment, ce qui est probablement stocké une référence à l' Looper
en ThreadLocal
.)
Avec un Handler
, vous pouvez les appeler post()
pour "mettre un message dans le thread de message de la file d'attente" (façon de parler). L' Handler
prendra soin de tous les IdleHandler
rappel des trucs et assurez-vous que votre posté Runnable
est exécutée. (Il peut également vérifier si le moment est venu déjà, si vous avez publiés avec un retard.)
Juste pour être clair: la seule façon de réellement faire une boucle de fil de faire quelque chose est de poster un message en boucle. Ceci est valable jusqu'à ce que vous appelez quit() sur le looper.
Concernant l'INTERFACE utilisateur android thread: À un certain point (et sans doute avant tout des activités et la comme sont créés) le cadre a mis en place un Looper
(contenant un MessageQueue
) et l'a commencée. À partir de ce moment, tout ce qui se passe sur le thread de l'INTERFACE utilisateur à travers cette boucle. Cela inclut l'activité de gestion du cycle de vie et ainsi de suite. Tous les rappels que vous override (onCreate()
, onDestroy()
...) sont au moins indirecty expédiés à partir de cette boucle. Vous pouvez voir que, par exemple, dans la trace de la pile d'exception. (Vous pouvez l'essayer, il suffit d'écrire int a = 1 / 0;
quelque part en onCreate()
...)
J'espère que cela a du sens. Désolé d'être peu clair auparavant.