Comment détecter le fil de l'interface utilisateur sur Android?

117

Existe-t-il un moyen robuste de détecter si Thread.currentThread()le thread d'interface utilisateur du système Android est dans une application?
Je voudrais mettre quelques affirmations dans mon code de modèle qui affirme qu'un seul thread ( par exemple le thread ui) accède à mon état, pour m'assurer qu'aucun type de synchronisation n'est nécessaire.

ParDroid
la source
Voir ma réponse ici: stackoverflow.com/a/41280460/878126
développeur android

Réponses:

199

La pratique courante pour déterminer l'identité du thread d'interface utilisateur est via Looper # getMainLooper :

if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}

À partir du niveau d'API 23 et plus, il existe une approche légèrement plus lisible en utilisant la nouvelle méthode d'assistance isCurrentThread sur le boucleur principal:

if (Looper.getMainLooper().isCurrentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}
mik3y
la source
6
stackoverflow.com/questions/11411022/... Cette réponse est bien aussi)
UnknownJoe
44

Je pense que la meilleure façon est la suivante:

 if (Looper.getMainLooper().equals(Looper.myLooper())) {
     // UI thread
 } else {
     // Non UI thread
 }
Atome
la source
Fonctionne très bien. Je vous remercie!
Hong
3
Pas besoin d'utiliser equalspuisque nous ne comparons que des références, et en plus de cela, elles sont toutes les deux statiques.
mr5
8

À partir du niveau 23 de l'API, il Looperexiste une belle méthode d'aide isCurrentThread. Vous pouvez obtenir le mainLooperet voir si c'est celui du thread actuel de cette façon:

Looper.getMainLooper().isCurrentThread()

C'est pratiquement la même chose que:

Looper.getMainLooper().getThread() == Thread.currentThread()

mais cela pourrait être un peu plus lisible et plus facile à retenir.

stan0
la source
2

En plus de vérifier le boucleur , si vous avez déjà essayé de vous déconnecter de l' ID de thread onCreate(), vous pourriez trouver que l' ID de thread d'interface utilisateur (thread principal) est toujours égal à 1. Par conséquent

if (Thread.currentThread().getId() == 1) {
    // UI thread
}
else {
    // other thread
}
yushulx
la source
Je ne trouve aucune documentation officielle qui corrobore que cela est vrai et le sera toujours. avez vous un lien?
intrepidis
C'est ce que j'ai trouvé dans logcat lorsque je souhaite surveiller le comportement multi-thread. Vous pouvez essayer de sortir l'ID de thread
yushulx
8
Je déconseille fortement cela, car cette valeur peut être spécifique à votre appareil et / ou à la version d'Android. Même si c'était le cas sur tous les appareils Android à l'heure actuelle, il n'y a aucune garantie que cela continuera d'être le cas dans les versions ultérieures. Enregistrer l'ID de thread dans un membre de la classe lors de l'exécution de onCreate () me semble un peu plus raisonnable.
personne3000
1

N'avez-vous pas pu utiliser la runOnUiThreadméthode dans la Activityclasse? Voir ..

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29

ridoy
la source
4
Mon application fonctionne, mais elle a plusieurs auteurs et devient plutôt grande et complexe. Ce que je veux faire, c'est ajouter un filet de sécurité supplémentaire, une affirmation qui intercepte l'erreur si quelqu'un appelle une méthode qui est conçue pour être appelée uniquement à partir du thread GUI d'un autre thread.
ParDroid
Je corrige actuellement un bug où l'utilisation de runOnUiThread provoque le flash de l'UX.
fobbymaster