Jak wykryć wątek interfejsu użytkownika na Androidzie?

117

Czy istnieje skuteczny sposób wykrywania, czy Thread.currentThread()w aplikacji jest wątek interfejsu użytkownika systemu Android?
Chciałbym umieścić w kodzie modelu pewne potwierdzenia, które zapewniają, że tylko jeden wątek ( np . Wątek interfejsu użytkownika) ma dostęp do mojego stanu, aby zapewnić, że nie jest konieczna żadna synchronizacja.

ParDroid
źródło
Zobacz moją odpowiedź tutaj: stackoverflow.com/a/41280460/878126
programista Androida

Odpowiedzi:

199

Typową praktyką określania tożsamości wątku interfejsu użytkownika jest metoda Looper # getMainLooper :

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

Począwszy od poziomu API 23 i nowszych , istnieje nieco bardziej czytelne podejście przy użyciu nowej metody pomocniczej isCurrentThread w głównym looper:

if (Looper.getMainLooper().isCurrentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}
mik3y
źródło
6
stackoverflow.com/questions/11411022/… Ta odpowiedź też jest miła)
UnknownJoe
44

Myślę, że najlepszy sposób to:

 if (Looper.getMainLooper().equals(Looper.myLooper())) {
     // UI thread
 } else {
     // Non UI thread
 }
Atom
źródło
Działa świetnie. Dziękuję Ci!
Hong
3
Nie ma potrzeby używania, equalsponieważ porównujemy tylko odwołania, a ponadto oba są statyczne.
mr5,
8

Od poziomu API 23 Looperma przyjemną metodę pomocniczą isCurrentThread. Możesz pobrać mainLooperi sprawdzić, czy to ten dla bieżącego wątku w ten sposób:

Looper.getMainLooper().isCurrentThread()

To praktycznie to samo, co:

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

ale mogłoby być trochę bardziej czytelne i łatwiejsze do zapamiętania.

stan0
źródło
2

Oprócz sprawdzenia looper , jeśli kiedykolwiek próbowałeś wylogować się z identyfikatora wątku onCreate(), możesz znaleźć identyfikator wątku interfejsu użytkownika (wątku głównego) zawsze równy 1. Dlatego

if (Thread.currentThread().getId() == 1) {
    // UI thread
}
else {
    // other thread
}
yushulx
źródło
Nie mogę znaleźć żadnej oficjalnej dokumentacji potwierdzającej, że to prawda i zawsze tak będzie. Czy masz link?
intrepidis
To właśnie znalazłem w logcat, gdy chcę monitorować zachowanie wielowątkowe. Możesz spróbować wyświetlić identyfikator wątku
yushulx
8
Zdecydowanie odradzam to, ponieważ ta wartość może być specyficzna dla twojego urządzenia i / lub wersji Androida. Nawet gdyby tak było teraz na każdym urządzeniu z Androidem, nie ma gwarancji, że będzie tak nadal w późniejszych wersjach. Zapisywanie identyfikatora wątku w elemencie klasy podczas uruchamiania onCreate () wydaje mi się nieco bardziej rozsądne.
personne3000
1

Czy nie mógłbyś użyć tej runOnUiThreadmetody w Activityklasie?

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

ridoy
źródło
4
Moja aplikacja działa, ale ma kilku autorów i staje się dość duża i złożona. To, co chcę zrobić, to dodać dodatkową siatkę bezpieczeństwa, potwierdzenie, które wychwytuje błąd, jeśli ktoś wywołuje metodę, która została zaprojektowana tak, aby była wywoływana tylko z wątku GUI z innego wątku.
ParDroid
Obecnie naprawiam błąd polegający na tym, że użycie runOnUiThread powoduje flashowanie UX.
fobbymaster