Мені потрібно перевірити, чи потік, на якому працює певний фрагмент коду, є основним (UI) потоком чи ні. Як я можу цього досягти?
Мені потрібно перевірити, чи потік, на якому працює певний фрагмент коду, є основним (UI) потоком чи ні. Як я можу цього досягти?
Відповіді:
Looper.myLooper() == Looper.getMainLooper()
якщо це повернеться правдою, значить, ви на потоці інтерфейсу користувача!
ви можете використовувати код нижче, щоб дізнатися, чи поточний потік - це UI / Main thread чи ні
if(Looper.myLooper() == Looper.getMainLooper()) {
// Current Thread is Main Thread.
}
або ви також можете використовувати це
if(Looper.getMainLooper().getThread() == Thread.currentThread()) {
// Current Thread is Main Thread.
}
Looper.myLooper()
поверне null, якщо потік не асоційований із Looper. Таким чином, обидва безпечні і мають однаковий результат, але перший трохи повільніше, коли він шукає всередині карти, щоб дізнатися петлю та пов’язані з нею нитки та виконувати деякі інші речі.
Найкращий спосіб - це найясніший і надійний спосіб: *
Thread.currentThread().equals( Looper.getMainLooper().getThread() )
Або, якщо платформа для виконання працює на рівні API 23 (Marshmallow 6.0) або вище:
Looper.getMainLooper().isCurrentThread()
Див. API Looper . Зауважте, що виклик Looper.getMainLooper()
включає синхронізацію (див. Джерело ). Ви можете уникнути накладних витрат, зберігаючи повернене значення та повторно використовуючи його.
* кредит greg7gkb та 2cupsOfTech
Looper.myLooper() == Looper.getMainLooper()
, що, на мою думку, менш зрозуміле. Я кредитую greg7gkb.
equals
, і тому відновлюється ==
, але це може змінитися в майбутньому. Тому я виправив відповідь.
Підсумовуючи рішення, я думаю, що це найкраще:
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
}
});
Ви можете перевірити
if(Looper.myLooper() == Looper.getMainLooper()) {
// You are on mainThread
}else{
// you are on non-ui thread
}
Дозвольте мені передмовити це: я визнав, що ця публікація має тег "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
}
Трохи зніяковівши, я шукав, перш ніж згадати це, але сподіваюся, це допоможе комусь іншому!
ви можете перевірити це в logcat android ddms, де ідентифікатор процесу буде однаковим, але ідентифікатор потоку буде іншим.
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
}
Ви можете спробувати Thread.currentThread (). IsDaemon ()