Як перевірити, чи поточна нитка не є основною


Відповіді:


707
Looper.myLooper() == Looper.getMainLooper()

якщо це повернеться правдою, значить, ви на потоці інтерфейсу користувача!


Як запустити цей код у червні?
Джон Сардінья

122

ви можете використовувати код нижче, щоб дізнатися, чи поточний потік - це UI / Main thread чи ні

if(Looper.myLooper() == Looper.getMainLooper()) {
   // Current Thread is Main Thread.
}

або ви також можете використовувати це

if(Looper.getMainLooper().getThread() == Thread.currentThread()) {
   // Current Thread is Main Thread.
}

Ось подібне питання


8
Чи слід вважати останній більш безпечним варіантом, оскільки немає гарантії, що будь-яка довільна нитка асоціюється із петлею (якщо припустити, що головна нитка завжди асоціюється із петлею)?
Янус Вармакен

Looper.myLooper()поверне null, якщо потік не асоційований із Looper. Таким чином, обидва безпечні і мають однаковий результат, але перший трохи повільніше, коли він шукає всередині карти, щоб дізнатися петлю та пов’язані з нею нитки та виконувати деякі інші речі.
Саїд Масумі

59

Найкращий спосіб - це найясніший і надійний спосіб: *

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

Або, якщо платформа для виконання працює на рівні API 23 (Marshmallow 6.0) або вище:

Looper.getMainLooper().isCurrentThread()

Див. API Looper . Зауважте, що виклик Looper.getMainLooper()включає синхронізацію (див. Джерело ). Ви можете уникнути накладних витрат, зберігаючи повернене значення та повторно використовуючи його.

   * кредит greg7gkb та 2cupsOfTech


Що ви маєте на увазі під "під API 23 або вище"? Для мене це не має великого сенсу ... Так само таку ж відповідь було опубліковано Анаккітом, внизу ..
Майк

@Mike Спасибі, я виправив біт API. AAnkit насправді виступає Looper.myLooper() == Looper.getMainLooper(), що, на мою думку, менш зрозуміле. Я кредитую greg7gkb.
Майкл Аллан

1
це має бути порівняння з == або дорівнює (), оскільки Android Studio викликає попередження?
2cupsOfTech

@ 2cupsOfTech По другій думці, це хороша порада. В даний час обидва тести є однаковими під час виконання, тому що Thread не переосмислюється equals, і тому відновлюється ==, але це може змінитися в майбутньому. Тому я виправив відповідь.
Майкл Аллан

25

Підсумовуючи рішення, я думаю, що це найкраще:

boolean isUiThread = VERSION.SDK_INT >= VERSION_CODES.M 
    ? Looper.getMainLooper().isCurrentThread()
    : Thread.currentThread() == Looper.getMainLooper().getThread();

І якщо ви хочете щось запустити на потоці інтерфейсу, ви можете скористатися цим:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
       //this runs on the UI thread
    }
});


2

Дозвольте мені передмовити це: я визнав, що ця публікація має тег "Android", однак мій пошук не має нічого спільного з "Android", і це був мій найкращий результат. З цією метою для користувачів, які не належать до Android SO Java, приземлившись тут, не забувайте про:

public static void main(String[] args{
    Thread.currentThread().setName("SomeNameIChoose");
    /*...the rest of main...*/
}

Встановивши це, в іншому місці вашого коду, ви можете легко перевірити, чи збираєтеся ви виконати в основному потоці за допомогою:

if(Thread.currentThread().getName().equals("SomeNameIChoose"))
{
    //do something on main thread
}

Трохи зніяковівши, я шукав, перш ніж згадати це, але сподіваюся, це допоможе комусь іншому!


1

ви можете перевірити це в logcat android ddms, де ідентифікатор процесу буде однаковим, але ідентифікатор потоку буде іншим.


1

Xamarin.Androidпорт: ( C#)

public bool IsMainThread => Build.VERSION.SdkInt >= BuildVersionCodes.M
    ? Looper.MainLooper.IsCurrentThread
    : Looper.MyLooper() == Looper.MainLooper;

Використання:

if (IsMainThread) {
    // you are on UI/Main thread
}

-6

Ви можете спробувати Thread.currentThread (). IsDaemon ()


Я не впевнений, що потік інтерфейсу є демон, але я буду вірити вам у цьому. Але як ти зможеш змінити тему Daemon, яку я міг (але не повинен) створити.
AxelH

Я перевірив у своєму веб-додатку, він показує, що потік інтерфейсу є потоком Daemon. Я поставив кілька моментів налагодження налагодження в середовищі затемнення і перевірив це. Детальніше про нитку показано як Нитка [http-bio-8080-exec-7,5, main]. Клацнув на деяких сторінках інтерфейсу і перевірив точку налагодження.
Шайлендра Сінгх

Крім того, навіть якщо в імені потоку детально вказано його "main", але виклик setDaemon (true) на об'єкт потоку зробить його демоном.
Шайлендра Сінгх

Ви не прочитали хорошої частини ... Я не сумнівався (повністю) у тому, що це Демон, я говорив, що ви не можете зробити відмінності з іншою такою ниткою Демона.
AxelH

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