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


Antworten:


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

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


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


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


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
    }
});

6

Du kannst nachschauen

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

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!


1

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


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
}

-6

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


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.)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.