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


117

Есть ли надежный способ определить, присутствует ли Thread.currentThread()поток пользовательского интерфейса системы 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.
}

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

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



2

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

if (Thread.currentThread().getId() == 1) {
    // UI thread
}
else {
    // other thread
}

Я не могу найти никакой официальной документации, подтверждающей, что это правда, и так будет всегда. У вас есть ссылка?
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


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

В настоящее время я исправляю ошибку, из-за которой использование runOnUiThread вызывает мигание UX.
fobbymaster
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.