Как определить поток пользовательского интерфейса на Android?

117

Есть ли надежный способ определить, присутствует ли Thread.currentThread()поток пользовательского интерфейса системы Android в приложении?
Я хотел бы добавить в код моей модели некоторые утверждения, которые утверждают, что только один поток ( например, поток пользовательского интерфейса) получает доступ к моему состоянию, чтобы гарантировать, что никакая синхронизация не требуется.

ParDroid
источник
См. Мой ответ здесь: stackoverflow.com/a/41280460/878126
разработчик Android

Ответы:

199

Обычная практика определения идентичности потока пользовательского интерфейса - через Looper # getMainLooper :

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

Начиная с уровня API 23 и выше, существует немного более читаемый подход с использованием нового вспомогательного метода isCurrentThread в основном цикле:

if (Looper.getMainLooper().isCurrentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}
mik3y
источник
6
stackoverflow.com/questions/11411022/… Этот ответ тоже хорош)
UnknownJoe
44

Я думаю, что лучший способ таков:

 if (Looper.getMainLooper().equals(Looper.myLooper())) {
     // UI thread
 } else {
     // Non UI thread
 }
Атом
источник
Прекрасно работает. Спасибо!
Гонконг
3
Нет необходимости использовать, equalsпоскольку мы только сравниваем ссылки, и, кроме того, они оба статичны.
mr5
8

Начиная с уровня API 23, у Looperнего есть хороший вспомогательный метод isCurrentThread. Вы можете получить mainLooperи посмотреть, подходит ли он для текущего потока, следующим образом:

Looper.getMainLooper().isCurrentThread()

Практически то же самое, что:

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

но он мог бы быть немного более читаемым и более легким для запоминания.

stan0
источник
2

Помимо проверки петлителя , если вы когда-либо пытались выйти из системы с идентификатором потока onCreate(), вы можете обнаружить, что идентификатор потока пользовательского интерфейса (основного потока) всегда равен 1. Поэтому

if (Thread.currentThread().getId() == 1) {
    // UI thread
}
else {
    // other thread
}
yushulx
источник
Я не могу найти никакой официальной документации, подтверждающей, что это правда, и так будет всегда. У вас есть ссылка?
intrepidis
Это то, что я обнаружил в logcat, когда хочу отслеживать многопоточное поведение. Вы можете попробовать вывести идентификатор потока
yushulx
8
Я настоятельно не рекомендую этого делать, так как это значение может быть специфическим для вашего устройства и / или версии Android. Даже если бы это было так на всех устройствах Android прямо сейчас, нет никакой гарантии, что так будет и в более поздних версиях. Мне кажется более разумным сохранение идентификатора потока в члене класса при запуске onCreate ().
personne3000
1

Не могли бы вы использовать runOnUiThreadметод в Activityклассе?

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

ridoy
источник
4
Мое приложение работает, но у него несколько авторов, и оно становится довольно большим и сложным. Что я хочу сделать, так это добавить дополнительную сеть безопасности, утверждение, которое улавливает ошибку, если кто-то вызывает метод, который предназначен для вызова только из потока графического интерфейса пользователя из другого потока.
ParDroid
В настоящее время я исправляю ошибку, из-за которой использование runOnUiThread вызывает мигание UX.
fobbymaster