Cara memeriksa apakah utas saat ini bukan utas utama


Jawaban:


709
Looper.myLooper() == Looper.getMainLooper()

jika ini mengembalikan true, maka Anda berada di utas UI!


Bagaimana Anda menjalankan kode ini di junit?
John Sardinha

123

Anda dapat menggunakan kode di bawah ini untuk mengetahui apakah utas saat ini adalah UI / Utas utama atau tidak

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

atau Anda juga bisa menggunakan ini

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

Ini pertanyaan serupa


8
Haruskah seseorang menganggap yang terakhir sebagai opsi yang lebih aman karena tidak ada jaminan bahwa utas sewenang-wenang apapun terkait dengan Looper (dengan asumsi bahwa utas utama selalu dikaitkan dengan looper)?
Janus Varmarken

Looper.myLooper()akan mengembalikan nol jika utas tidak dikaitkan dengan Looper. Jadi keduanya aman dan memiliki hasil yang sama tetapi yang pertama sedikit lebih lambat saat mencari di dalam peta untuk mengetahui looper dan utas terkait dan melakukan beberapa hal lainnya.
Saeed Masoumi

59

Cara terbaik adalah cara yang paling jelas, paling kuat: *

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

Atau, jika platform runtime adalah API level 23 (Marshmallow 6.0) atau lebih tinggi:

Looper.getMainLooper().isCurrentThread()

Lihat Looper API . Perhatikan bahwa panggilan Looper.getMainLooper()melibatkan sinkronisasi (lihat sumbernya ). Anda mungkin ingin menghindari overhead dengan menyimpan nilai kembali dan menggunakannya kembali.

   * kredit greg7gkb dan 2cupsOfTech


Apa yang Anda maksud dengan "di bawah API 23 atau lebih tinggi"? Itu tidak masuk akal bagi saya..Juga jawaban yang sama persis diposting oleh AAnkit, di bawah ini ..
Mike

@ Mike Terima kasih, saya memperbaiki bit API. AAnkit sebenarnya nikmat Looper.myLooper() == Looper.getMainLooper(), yang menurut saya kurang jelas. Saya kredit greg7gkb.
Michael Allan

1
haruskah ini perbandingan dengan == atau sama dengan () karena Android Studio meningkatkan peringatan?
2cupsOfTech

@ 2cupsOfTech Pada pemikiran kedua, itu saran yang bagus. Saat ini kedua tes adalah sama pada saat runtime karena Thread tidak menimpa equals, dan jatuh kembali ke ==, tetapi itu bisa berubah di masa depan. Jadi saya mengoreksi jawabannya.
Michael Allan

25

Merangkum solusi, saya pikir itu yang terbaik:

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

Dan, jika Anda ingin menjalankan sesuatu pada utas UI, Anda dapat menggunakan ini:

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

6

Anda bisa mengeceknya

if(Looper.myLooper() == Looper.getMainLooper()) {
   // You are on mainThread 
}else{
// you are on non-ui thread
}

2

Izinkan saya untuk mengawali ini dengan: Saya mengakui posting ini memiliki tag 'Android', namun, pencarian saya tidak ada hubungannya dengan 'Android' dan ini adalah hasil teratas saya. Untuk itu, untuk pengguna SO Java non-Android yang mendarat di sini, jangan lupakan:

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

Setelah mengatur ini, di tempat lain dalam kode Anda, Anda dapat dengan mudah memeriksa apakah Anda akan mengeksekusi di utas utama dengan:

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

Agak malu saya telah mencari sebelum mengingat ini, tapi mudah-mudahan itu akan membantu orang lain!


1

Anda dapat memverifikasinya di android ddms logcat di mana id proses akan sama tetapi id utas akan berbeda.


1

Xamarin.Androidport: ( C#)

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

Pemakaian:

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

-6

Anda dapat mencoba Thread.currentThread (). IsDaemon ()


Saya tidak yakin utas UI adalah daemon tetapi saya akan mempercayai Anda tentang ini. Tetapi bagaimana Anda akan membuat perbedaan dengan Daemon Thread yang saya dapat (tetapi tidak seharusnya) buat.
AxelH

Saya menguji di aplikasi web saya, itu menunjukkan bahwa utas UI adalah utas Daemon. Saya menaruh beberapa break point debug di lingkungan gerhana dan memverifikasinya. Detail utas ditampilkan sebagai Utas [http-bio-8080-exec-7,5, utama]. Mengklik pada beberapa halaman UI dan memeriksa titik debug.
Shailendra Singh

Juga, bahkan jika dalam nama thread rinciannya menampilkan 'main' tetapi memanggil setDaemon (true) pada objek thread akan membuatnya daemon.
Shailendra Singh

Anda tidak membaca bagian yang baik ... Saya tidak ragu-ragu (sepenuhnya) tentang itu menjadi Daemon, saya mengatakan bahwa Anda tidak dapat membuat perbedaan dengan utas Daemon lain seperti ini.
AxelH

Dengan kata lain: utas utama mungkin merupakan utas daemon, tetapi tidak semua utas daemon adalah utas utama. (Mengidentifikasi utas utama adalah apa yang ditanyakan di sini.)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.