So überprüfen Sie, ob der aktuelle Thread kein Haupt-Thread ist

391

Ich muss überprüfen, ob der Thread, auf dem ein bestimmter Code ausgeführt wird, der Hauptthread (UI) ist oder nicht. Wie kann ich das erreichen?

Charlie-Blake
quelle
Beispiel mit Thread-Beispiel zu demonstrieren code2concept.blogspot.in/2015/02/…
nitesh

Antworten:

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

Wenn dies true zurückgibt, befinden Sie sich im UI-Thread!

Fleischlich
quelle
Wie führt man diesen Code in junit aus?
John Sardinha
122

Sie können den folgenden Code verwenden, um festzustellen, ob der aktuelle Thread UI / Main Thread ist oder nicht

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

oder Sie können dies auch verwenden

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

Hier ist eine ähnliche Frage

AAnkit
quelle
8
Sollte man Letzteres als sicherere Option betrachten, da es keine Garantie dafür gibt, dass ein beliebiger Thread einem Looper zugeordnet ist (vorausgesetzt, der Haupt-Thread ist immer einem Looper zugeordnet)?
Janus Varmarken
Looper.myLooper()gibt null zurück, wenn der Thread keinem Looper zugeordnet ist. Beide sind also sicher und haben das gleiche Ergebnis, aber das erste ist etwas langsamer, während es in einer Karte sucht, um den Looper und den zugehörigen Thread herauszufinden und andere Dinge zu tun.
Saeed Masoumi
59

Der beste Weg ist der klarste und robusteste: *

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

Oder wenn die Laufzeitplattform API-Level 23 (Marshmallow 6.0) oder höher ist:

Looper.getMainLooper().isCurrentThread()

Siehe die Looper-API . Beachten Sie, dass das Aufrufen Looper.getMainLooper()eine Synchronisierung beinhaltet (siehe Quelle ). Möglicherweise möchten Sie den Overhead vermeiden, indem Sie den Rückgabewert speichern und wiederverwenden.

   * Kredit greg7gkb und 2cupsOfTech

Michael Allan
quelle
Was meinst du mit "unter API 23 oder höher"? Das macht für mich nicht viel Sinn. Auch die exakt gleiche Antwort wurde von AAnkit unten gepostet.
Mike
@ Mike Danke, ich habe das API-Bit behoben. AAnkit bevorzugt tatsächlich Looper.myLooper() == Looper.getMainLooper(), was meiner Meinung nach weniger klar ist. Ich schreibe greg7gkb gut.
Michael Allan
1
Sollte dies ein Vergleich mit == oder equals () sein, da Android Studio eine Warnung auslöst?
2cupsOfTech
@ 2cupsOfTech Beim zweiten Gedanken ist das ein guter Rat. Derzeit sind beide Tests zur Laufzeit gleich, da Thread nicht überschreibt equalsund daher zurückfällt. Dies ==könnte sich jedoch in Zukunft ändern. Also habe ich die Antwort korrigiert.
Michael Allan
25

Zusammenfassend denke ich, dass dies die beste ist:

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

Und wenn Sie etwas auf dem UI-Thread ausführen möchten, können Sie Folgendes verwenden:

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

Du kannst nachschauen

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

Gestatten Sie mir Folgendes: Ich habe bestätigt, dass dieser Beitrag das Tag "Android" enthält. Meine Suche hatte jedoch nichts mit "Android" zu tun, und dies war mein Top-Ergebnis. Vergessen Sie zu diesem Zweck für Nicht-Android- SO-Java-Benutzer, die hier landen, Folgendes nicht:

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

Nachdem Sie dies an einer anderen Stelle in Ihrem Code festgelegt haben, können Sie leicht überprüfen, ob Sie im Hauptthread Folgendes ausführen möchten:

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

Ein bisschen verlegen hatte ich gesucht, bevor ich mich daran erinnerte, aber hoffentlich hilft es jemand anderem!

ThatOneGuy
quelle
1

Sie können es in android ddms logcat überprüfen, wo die Prozess-ID identisch ist, die Thread-ID jedoch unterschiedlich ist.

Vishwanath.M
quelle
1

Xamarin.AndroidHafen: ( C#)

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

Verwendungszweck:

if (IsMainThread) {
    // you are on UI/Main thread
}
Mehdi Dehghani
quelle
-6

Sie können Thread.currentThread (). IsDaemon () ausprobieren

Shailendra Singh
quelle
Ich bin nicht sicher, ob der UI-Thread ein Daemon ist, aber ich werde Ihnen in diesem Fall glauben. Aber wie können Sie mit einem Daemon-Thread, den ich erstellen konnte (aber nicht sollte), den Unterschied machen?
AxelH
Ich habe in meiner Web-App getestet, dass der UI-Thread ein Daemon-Thread ist. Ich habe einige Debug-Haltepunkte in die Eclipse-Umgebung eingefügt und diese überprüft. Thread-Detail als Thread [http-bio-8080-exec-7,5, main] angezeigt. Klicken Sie auf einige UI-Seiten und überprüfen Sie den Debug-Punkt.
Shailendra Singh
Auch wenn in den Details des Thread-Namens 'main' angezeigt wird, aber setDaemon (true) für das Thread-Objekt aufruft, wird es zum Daemon.
Shailendra Singh
Du hast den guten Teil nicht gelesen ... Ich habe nicht (vollständig) daran gezweifelt, dass es sich um einen Daemon handelt. Ich habe gesagt, dass du mit einem anderen Daemon-Thread wie diesem keinen Unterschied machen kannst.
AxelH
Anders ausgedrückt: Ein Haupt-Thread kann ein Daemon-Thread sein, aber nicht alle Daemon-Threads sind der Haupt-Thread. (Die Identifizierung des Hauptthreads ist das, was hier gefragt wird.)