Geçerli iş parçacığının ana iş parçacığı olup olmadığı nasıl denetlenir


Yanıtlar:


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

bu doğruysa, kullanıcı arayüzünde olursunuz!


Junit'te bu kodu nasıl çalıştırıyorsunuz?
John Sardinha

122

mevcut iş parçacığının UI / Ana iş parçacığı olup olmadığını öğrenmek için aşağıdaki kodu kullanabilirsiniz

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

veya bunu da kullanabilirsiniz

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

İşte benzer soru


8
İkincisi daha güvenli bir seçenek olarak düşünülmelidir, çünkü bir Looper ile keyfi bir ipliğin ilişkili olduğunu garanti etmez (ana ipliğin her zaman bir lüper ile ilişkili olduğu varsayılarak)?
Janus Varmarken

Looper.myLooper()iş parçacığı bir Lüper ile ilişkili değilse null değerini döndürür. Bu yüzden her ikisi de güvenlidir ve aynı sonuca sahiptir, ancak birincisi, lüper ve onunla ilişkili iş parçacığını bulmak ve başka şeyler yapmak için bir harita içinde ararken biraz daha yavaştır.
Saeed Masoumi

59

En iyi yol en net, en sağlam yol: *

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

Veya çalışma zamanı platformu API düzey 23 (Marshmallow 6.0) veya daha yüksekse:

Looper.getMainLooper().isCurrentThread()

Lüper API'sine bakın . Looper.getMainLooper()Çağrının senkronizasyon içerdiğini unutmayın ( kaynağa bakın ). Dönüş değerini kaydedip yeniden kullanarak ek yükten kaçınmak isteyebilirsiniz.

   * kredi greg7gkb ve 2cupsOfTech


"API 23 veya üstü altında" ile ne demek istiyorsun? Bu bana pek mantıklı değil ... Aynı cevabı aşağıda AAnkit, asıldı ..
Mike

@Mike Teşekkürler, API bitini düzelttim. AAnkit aslında Looper.myLooper() == Looper.getMainLooper()daha az net olduğunu düşünüyorum. Ben greg7gkb kredi.
Michael Allan

1
, Android Studio bir uyarı oluşturduğundan == veya equals () ile karşılaştırmalı mıdır?
2cupsOfTech

@ 2cupsOfTech 2. düşünce üzerine, bu iyi bir tavsiye. İş parçacığı geçersiz kılmadığından equalsve geri düştüğü için şu anda her iki test de çalışma zamanında aynıdır ==, ancak bu gelecekte değişebilir. Bu yüzden cevabı düzelttim.
Michael Allan

25

Çözümleri özetlersek, bunun en iyisi olduğunu düşünüyorum:

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

UI iş parçacığında bir şey çalıştırmak istiyorsanız, bunu kullanabilirsiniz:

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

6

Kontrol edebilirsin

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

2

Bunu önceden yazmama izin ver: Bu yayının 'Android' etiketine sahip olduğunu kabul ettim, ancak aramamın 'Android' ile ilgisi yoktu ve bu benim en iyi sonucumdu. Bu amaçla, buraya gelen Android olmayan SO Java kullanıcıları için şunları unutmayın:

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

Bunu ayarladıktan sonra, kodunuzun başka bir yerinde, ana iş parçacığında aşağıdakilerle yürütmek üzere olup olmadığınızı kolayca kontrol edebilirsiniz:

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

Bunu hatırlamadan önce biraz utandım, ama umarım başka birine yardımcı olur!


1

süreç kimliği aynı olacak ama iş parçacığı kimliği farklı olacak android ddms logcat doğrulayabilirsiniz.


1

Xamarin.Androidbağlantı noktası: ( C#)

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

Kullanımı:

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

-6

Thread.currentThread (). Deneyebilirsiniz isDaemon ()


UI iş parçacığının bir daemon olduğundan emin değilim ama size bu konuda inanacağım. Ancak, oluşturabildiğim (ancak yapmamam gereken) bir Daemon Thread ile farkı nasıl yaratacaksınız?
AxelH

Web uygulamamda test ettim, UI iş parçacığının Daemon iş parçacığı olduğunu gösteriyor. Tutulma ortamına bazı hata ayıklama kesme noktaları koydum ve doğruladım. İş parçacığı ayrıntısı İş Parçacığı [http-bio-8080-exec-7,5, main] olarak gösterilir. Bazı kullanıcı arayüzü sayfalarını tıkladı ve hata ayıklama noktasını kontrol etti.
Shailendra Singh

Ayrıca, iş parçacığı adında bile 'ana' gösteriliyor olsa da iş parçacığı nesnesinde setDaemon (true) çağrılması daemon yapacaktır.
Shailendra Singh

İyi kısmı okumadınız ... Bunun (Daemon) bir Daemon olduğundan şüphe etmedim, böyle bir Daemon iş parçacığıyla fark yaratamayacağınızı söylüyordum.
AxelH

Başka bir deyişle, ana iş parçacığı bir daemon iş parçacığı olabilir, ancak tüm daemon iş parçacığı ana iş parçacığı değildir. (Ana iş parçacığını tanımlamak burada sorulan şeydir.)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.