Cómo verificar si el hilo actual no es el hilo principal

Respuestas:

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

Si esto devuelve verdadero, entonces estás en el hilo de la interfaz de usuario.

Carnal
fuente
¿Cómo se ejecuta este código en junio?
John Sardinha
123

puede usar el siguiente código para saber si el hilo actual es UI / hilo principal o no

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

o también puedes usar esto

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

Aquí hay una pregunta similar

AAnkit
fuente
8
¿Debería considerarse esto último como la opción más segura ya que no hay garantía de que un hilo arbitrario esté asociado con un Looper (suponiendo que el hilo principal siempre esté asociado con un looper)?
Janus Varmarken
Looper.myLooper()devolverá nulo si el hilo no está asociado con un Looper. Por lo tanto, ambos son seguros y tienen el mismo resultado, pero el primero es un poco más lento mientras busca dentro de un mapa para descubrir el enlazador y su hilo asociado y hacer otras cosas.
Saeed Masoumi el
59

La mejor manera es la más clara y robusta: *

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

O, si la plataforma de tiempo de ejecución es API nivel 23 (Marshmallow 6.0) o superior:

Looper.getMainLooper().isCurrentThread()

Ver la API de Looper . Tenga en cuenta que las llamadas Looper.getMainLooper()implican sincronización (ver la fuente ). Es posible que desee evitar la sobrecarga almacenando el valor de retorno y reutilizándolo.

   * crédito greg7gkb y 2cupsOfTech

Michael Allan
fuente
¿Qué quiere decir con "bajo API 23 o superior"? Eso no tiene mucho sentido para mí ... También la misma respuesta exacta fue publicada por AAnkit, a continuación ...
Mike
@ Mike Gracias, arreglé el bit API. AAnkit en realidad favorece Looper.myLooper() == Looper.getMainLooper(), lo que creo que es menos claro. Le doy crédito a greg7gkb.
Michael Allan
1
¿Debería ser una comparación con == o equals () ya que Android Studio genera una advertencia?
2cupsOfTech
@ 2cupsOfTech Pensándolo bien, ese es un buen consejo. Actualmente, ambas pruebas son las mismas en tiempo de ejecución porque Thread no se anula equals, por lo que recurre a ==, pero eso podría cambiar en el futuro. Entonces corregí la respuesta.
Michael Allan
25

Resumiendo las soluciones, creo que esa es la mejor:

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

Y, si desea ejecutar algo en el hilo de la interfaz de usuario, puede usar esto:

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

Puedes comprobar

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

Permítanme presentar esto con anterioridad: reconocí que esta publicación tiene la etiqueta 'Android', sin embargo, mi búsqueda no tuvo nada que ver con 'Android' y este fue mi resultado principal. Con ese fin, para los usuarios de SO Java que no son Android que aterrizan aquí, no se olviden de:

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

Después de configurar esto, en otra parte de su código, puede verificar fácilmente si está a punto de ejecutar en el hilo principal con:

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

Un poco avergonzado había buscado antes de recordar esto, ¡pero espero que ayude a alguien más!

ThatOneGuy
fuente
1

puede verificarlo en android ddms logcat donde la identificación del proceso será la misma pero la identificación del hilo será diferente.

Vishwanath.M
fuente
1

Xamarin.Androidpuerto: ( 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
}
Mehdi Dehghani
fuente
-6

Puede probar Thread.currentThread (). IsDaemon ()

Shailendra Singh
fuente
No estoy seguro de que el hilo de la interfaz de usuario sea un demonio, pero te creeré en este caso. Pero, ¿cómo harás la diferencia con un hilo de daemon que podría (pero no debería) crear?
AxelH
Probé en mi aplicación web, muestra que el hilo de la interfaz de usuario es un hilo Daemon. Puse algunos puntos de ruptura de depuración en el entorno eclipse y lo verifiqué. El detalle del hilo se muestra como Hilo [http-bio-8080-exec-7,5, main]. Hice clic en algunas páginas de la IU y verificó el punto de depuración.
Shailendra Singh
Además, incluso si en los detalles del nombre del hilo se muestra 'main' pero llamando a setDaemon (true) en el objeto de hilo lo hará demonio.
Shailendra Singh
No leíste la parte buena ... No dudaba (completamente) de que fuera un Daemon, estaba diciendo que no puedes hacer las diferencias con otro hilo de Daemon como este.
AxelH
Dicho de otra manera: un hilo principal puede ser un hilo de demonio, pero no todos los hilos de demonio son el hilo principal. (Identificar el hilo principal es lo que se pregunta aquí.)