Come verificare se il thread corrente non è il thread principale


Risposte:


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

se questo ritorna vero, allora sei nel thread dell'interfaccia utente!


Come si esegue questo codice in junit?
John Sardinha,

123

puoi usare il codice qui sotto per sapere se il thread corrente è UI / thread principale o meno

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

oppure puoi anche usare questo

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

Ecco una domanda simile


8
Si dovrebbe considerare quest'ultimo come l'opzione più sicura in quanto non esiste alcuna garanzia che qualsiasi thread arbitrario sia associato a un Looper (supponendo che il thread principale sia sempre associato a un looper)?
Janus Varmarken,

Looper.myLooper()restituirà null se il thread non è associato a un Looper. Quindi entrambi sono sicuri e hanno lo stesso risultato, ma il primo è un po 'più lento mentre cerca all'interno di una mappa per scoprire il crochet e il thread associato e fare alcune altre cose.
Saeed Masoumi,

59

Il modo migliore è il modo più chiaro e robusto: *

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

Oppure, se la piattaforma di runtime è di livello API 23 (Marshmallow 6.0) o superiore:

Looper.getMainLooper().isCurrentThread()

Vedi l' API Looper . Si noti che la chiamata Looper.getMainLooper()comporta la sincronizzazione (vedere l' origine ). È possibile evitare l'overhead archiviando il valore restituito e riutilizzandolo.

   * credit greg7gkb e 2cupsOfTech


Cosa intendi con "sotto API 23 o successiva"? Questo non ha molto senso per me..Inoltre la stessa identica risposta è stata pubblicata da AAnkit, di seguito ..
Mike,

@Mike Grazie, ho corretto il bit API. AAnkit in realtà favorisce Looper.myLooper() == Looper.getMainLooper(), che penso sia meno chiaro. Accredito greg7gkb.
Michael Allan,

1
dovrebbe essere un confronto con == o uguale a () in quanto Android Studio sta generando un avviso?
2cupsOfTech,

@ 2cupsOfTech Al secondo pensiero, questo è un buon consiglio. Attualmente entrambi i test sono gli stessi in fase di esecuzione perché Thread non ha la precedenza equalse quindi ricade su ==, ma ciò potrebbe cambiare in futuro. Quindi ho corretto la risposta.
Michael Allan,

25

Riassumendo le soluzioni, penso che sia la migliore:

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

E, se desideri eseguire qualcosa sul thread dell'interfaccia utente, puoi utilizzare questo:

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

6

Puoi controllare

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

2

Consentitemi di prefigurare questo: ho riconosciuto che questo post ha il tag "Android", tuttavia, la mia ricerca non aveva nulla a che fare con "Android" e questo è stato il mio miglior risultato. A tal fine, per gli utenti SO Android non Android che atterrano qui, non dimenticare di:

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

Dopo aver impostato questo, altrove nel tuo codice, puoi facilmente verificare se stai per eseguire sul thread principale con:

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

Un po 'imbarazzato avevo cercato prima di ricordare questo, ma spero che possa aiutare qualcun altro!


1

puoi verificarlo in android ddms logcat dove l'id del processo sarà lo stesso ma l'id del thread sarà diverso.


1

Xamarin.Androidporto: ( C#)

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

Uso:

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

-6

Puoi provare Thread.currentThread (). IsDaemon ()


Non sono sicuro che il thread dell'interfaccia utente sia un demone ma ti crederò su questo. Ma come farai la differenza con un thread demone che potrei (ma non dovrei) creare.
AxelH,

Ho testato nella mia app Web, mostra che il thread dell'interfaccia utente è un thread Daemon. Ho inserito alcuni punti di interruzione del debug nell'ambiente eclipse e l'ho verificato. Dettaglio discussione mostrato come Discussione [http-bio-8080-exec-7,5, principale]. Facendo clic su alcune pagine dell'interfaccia utente e controllato il punto di debug.
Shailendra Singh,

Inoltre, anche se nei dettagli del nome del thread mostra 'main' ma la chiamata di setDaemon (true) sull'oggetto thread lo renderà demone.
Shailendra Singh,

Non hai letto la parte buona ... Non avevo dubbi (completamente) sul fatto che fosse un Daemon, stavo dicendo che non puoi fare le differenze con un altro thread Daemon come questo.
AxelH,

Detto in altro modo: un thread principale può essere un thread daemon, ma non tutti i thread daemon sono il thread principale. (Identificare il thread principale è ciò che viene richiesto qui.)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.