Як виявити потік інтерфейсу користувача на Android?


117

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


Дивіться мою відповідь тут: stackoverflow.com/a/41280460/878126
андроїд розробник

Відповіді:


199

Поширена практика для визначення особи інтерфейсу користувача через Looper # getMainLooper :

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

Починаючи з рівня 23 і вище API, є трохи більш читабельний підхід із використанням нового допоміжного методу isCurrentThread на головному петлі:

if (Looper.getMainLooper().isCurrentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}

6
stackoverflow.com/questions/11411022/… Ця відповідь також приємна)
НевідомоJoe

44

Я думаю, що найкращий спосіб такий:

 if (Looper.getMainLooper().equals(Looper.myLooper())) {
     // UI thread
 } else {
     // Non UI thread
 }

Чудово працює. Дякую!
Гонг

3
Не потрібно використовувати, equalsоскільки ми порівнюємо лише посилання, а крім того, вони обидва статичні.
mr5

8

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

Looper.getMainLooper().isCurrentThread()

Це практично те саме, що:

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

але це може бути трохи читабельніше та легше запам’ятати.



2

Окрім перевірки looper , якщо ви коли-небудь намагалися вийти з ідентифікатора потоку 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
Моя програма працює, але вона має декількох авторів і стає досить великою і складною. Що я хочу зробити, це додати додаткову мережу безпеки, ствердження, яке фіксує помилку, якщо хтось викликає метод, призначений для виклику лише з GUI-потоку з іншого потоку.
ParDroid

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