Soy nuevo en android. Quiero saber qué hace la Looper
clase y también cómo usarla. He leído la documentación de la clase Android Looper pero no puedo entenderla completamente. Lo he visto en muchos lugares pero no puedo entender su propósito. ¿Alguien puede ayudarme definiendo el propósito Looper
y también dando un ejemplo simple si es posible?
android
multithreading
android-looper
Khawar Raza
fuente
fuente
Respuestas:
¿Qué es looper?
Looper es una clase que se utiliza para ejecutar los mensajes (Runnables) en una cola. Los subprocesos normales no tienen esa cola, por ejemplo, el subproceso simple no tiene ninguna cola. Se ejecuta una vez y una vez que finaliza la ejecución del método, el hilo no ejecutará otro Mensaje (Ejecutable).
¿Dónde podemos usar la clase Looper?
Si alguien quiere ejecutar varios mensajes (Runnables), entonces debe usar la clase Looper que es responsable de crear una cola en el hilo. Por ejemplo, al escribir una aplicación que descarga archivos de Internet, podemos usar la clase Looper para colocar los archivos que se descargarán en la cola.
¿Cómo funciona?
Hay un
prepare()
método para preparar el Looper. Luego puede usar elloop()
método para crear un bucle de mensajes en el hilo actual y ahora su Looper está listo para ejecutar las solicitudes en la cola hasta que salga del bucle.Aquí está el código por el cual puede preparar el Looper.
fuente
Puede comprender mejor qué es Looper en el contexto del marco GUI. Looper está hecho para hacer 2 cosas.
1) Looper transforma un hilo normal , que termina cuando su método run () regresa, en algo que se ejecuta continuamente hasta que se ejecuta la aplicación de Android , lo cual es necesario en el marco de la GUI (Técnicamente, todavía termina cuando el método run () regresa. Pero déjame aclarar lo que quiero decir a continuación).
2) Looper proporciona una cola donde se ponen en cola los trabajos a realizar, que también es necesario en el marco de la GUI.
Como ya sabrá, cuando se inicia una aplicación, el sistema crea un subproceso de ejecución para la aplicación, denominado "principal", y las aplicaciones de Android normalmente se ejecutan completamente en un solo subproceso por defecto, el "subproceso principal". Pero el hilo principal no es un secreto, un hilo especial . Es solo un hilo normal similar a los hilos que creas con
new Thread()
código, lo que significa que termina cuando vuelve su método run (). Piense en el siguiente ejemplo.Ahora, apliquemos este principio simple a las aplicaciones de Android. ¿Qué pasaría si una aplicación de Android se ejecuta en hilo normal? Un hilo llamado "main" o "UI" o lo que sea que inicie su aplicación, y dibuja toda la IU. Entonces, la primera pantalla se muestra a los usuarios. ¿Y ahora qué? El hilo principal termina? No, no debería. Debería esperar hasta que los usuarios hagan algo, ¿verdad? Pero, ¿cómo podemos lograr este comportamiento? Bueno, podemos intentarlo con
Object.wait()
oThread.sleep()
. Por ejemplo, el subproceso principal finaliza su trabajo inicial para mostrar la primera pantalla y duerme. Se despierta, lo que significa interrumpido, cuando se busca un nuevo trabajo para hacer. Hasta ahora todo bien, pero en este momento necesitamos una estructura de datos similar a la cola para mantener múltiples trabajos. Piense en un caso en el que un usuario toca la pantalla en serie, y una tarea tarda más en terminar. Por lo tanto, necesitamos tener una estructura de datos para mantener los trabajos a realizar de primero en entrar, primero en salir. Además, puede imaginarse que implementar un subproceso que siempre se ejecuta y procesa el trabajo cuando se llega mediante la interrupción no es fácil y conduce a un código complejo y, a menudo, imposible de mantener. Preferimos crear un nuevo mecanismo para tal propósito, y de eso se trata Looper . El documento oficial de la clase Looper.dice: "Los subprocesos por defecto no tienen un bucle de mensajes asociado con ellos", y Looper es una clase "utilizada para ejecutar un bucle de mensajes para un subproceso". Ahora puedes entender lo que significa.Para aclarar las cosas, verifiquemos el código donde se transforma el hilo principal. Todo sucede en la clase ActivityThread . En su método main (), puede encontrar el siguiente código, que convierte un hilo principal normal en algo que necesitamos.
y
Looper.loop()
bucle de método infinitamente y retirar un mensaje y procesar uno a la vez:Entonces, básicamente Looper es una clase hecha para abordar un problema que ocurre en el marco de la GUI. Pero este tipo de necesidades también puede ocurrir en otra situación. En realidad, es un patrón bastante famoso para la aplicación de subprocesos múltiples, y puede obtener más información al respecto en " Programación concurrente en Java " de Doug Lea (Especialmente, el capítulo 4.1.4 "Subprocesos de trabajo" sería útil). Además, puede imaginar que este tipo de mecanismo no es único en el marco de Android, pero todo el marco de la GUI puede necesitar algo similar a esto. Puede encontrar casi el mismo mecanismo en el marco de Java Swing.
fuente
Looper permite que las tareas se ejecuten secuencialmente en un solo hilo. Y handler define aquellas tareas que necesitamos ejecutar. Es un escenario típico que estoy tratando de ilustrar en este ejemplo:
Ahora podemos usar el controlador en algunos otros hilos (digamos ui thread) para publicar la tarea en Looper para ejecutar.
En el hilo de la interfaz de usuario tenemos un Looper implícito que nos permite manejar los mensajes en el hilo de la interfaz de usuario.
fuente
Android
Looper
es un envoltorio para unirMessageQueue
aThread
y gestiona la cola de procesamiento. Se ve muy críptico en la documentación de Android y muchas veces podemos enfrentar problemasLooper
relacionados con el acceso a la interfaz de usuario. Si no entendemos los conceptos básicos, se vuelve muy difícil de manejar.Aquí hay un artículo que explica el
Looper
ciclo de vida, cómo usarlo y su usoLooper
enHandler
Looper = Hilo + MessageQueue
fuente
Definición de Looper & Handler:
Looper es una clase que convierte un subproceso en un subproceso y controlador de canalización le brinda un mecanismo para insertar tareas desde cualquier otro subproceso.
Detalles:
Por lo tanto, un hilo de PipeLine es un hilo que puede aceptar más tareas de otros hilos a través de un controlador.
El Looper se llama así porque implementa el bucle: toma la siguiente tarea, la ejecuta, luego toma la siguiente y así sucesivamente. El controlador se llama controlador porque se usa para manejar o aceptar la siguiente tarea cada vez desde cualquier otro subproceso y pasarlo a Looper (subproceso o subproceso de línea de tubería).
Ejemplo:
Un ejemplo perfecto de Looper and Handler o PipeLine Thread es descargar más de una imagen o subirlas a un servidor (Http) una por una en una sola secuencia en lugar de comenzar una nueva secuencia para cada llamada de red en segundo plano.
Lea más aquí sobre Looper and Handler y la definición de Pipeline Thread:
Android Guts: Introducción a Loopers y Handlers
fuente
Un Looper tiene un
synchronized
MessageQueue
que se utiliza para procesar mensajes colocados en la cola.Implementa un
Thread
patrón de almacenamiento específico.Solo uno
Looper
porThread
. Los métodos clave incluyenprepare()
,loop()
yquit()
.prepare()
inicializa la corrienteThread
como aLooper
.prepare()
es unstatic
método que usa laThreadLocal
clase como se muestra a continuación.prepare()
debe llamarse explícitamente antes de ejecutar el bucle de eventos.loop()
ejecuta el bucle de eventos que espera a que lleguen los mensajes en la cola de mensajes de un subproceso específico. Una vez que se recibe el siguiente mensaje, elloop()
método envía el mensaje a su controlador de destinoquit()
cierra el bucle de eventos. No termina el ciclo, sino que pone en cola un mensaje especialLooper
se puede programar enThread
varios pasosAmpliar
Thread
Llame
Looper.prepare()
para inicializar Thread como unLooper
Cree uno o más
Handler
para procesar los mensajes entrantesLooper.loop()
para procesar mensajes hasta que se indique el buclequit()
.fuente
La vida útil de Java Thread termina después de completar el
run()
método. El mismo hilo no se puede iniciar de nuevo.Looper transforma lo normal
Thread
en un bucle de mensajes. Los métodos clave deLooper
son:Este artículo de Mindorks de Janishar explica los conceptos básicos de una manera agradable.
Looper
está asociado con un hilo. Si necesitaLooper
un subproceso de interfaz de usuario,Looper.getMainLooper()
devolverá el subproceso asociado.Debe
Looper
estar asociado con un controlador .Looper
,Handler
yHandlerThread
son la forma en que Android soluciona los problemas de programación asincrónica.Una vez que lo haya hecho
Handler
, puede llamar a las siguientes API.HandlerThread es una clase útil para comenzar un nuevo hilo que tiene un looper. El looper se puede usar para crear clases de manejador
En algunos escenarios, no puede ejecutar
Runnable
tareas en UI Thread. Por ejemplo, operaciones de red: envíe un mensaje en un socket, abra una URL y obtenga contenido leyendoInputStream
En estos casos,
HandlerThread
es útil. Puede obtener unLooper
objetoHandlerThread
y crear un subprocesoHandler
enHandlerThread
lugar del hilo principal.El código de HandlerThread será así:
Consulte la publicación a continuación para obtener un código de ejemplo:
Android: tostadas en un hilo
fuente
Entendiendo los hilos Looper
Un Java Thread una unidad de ejecución que fue diseñada para realizar una tarea en su método run () y terminar después de eso:
Pero en Android hay muchos casos de uso en los que necesitamos mantener vivo un hilo y esperar las entradas / eventos del usuario, por ejemplo. UI thread aka
Main Thread
.El subproceso principal en Android es un subproceso de Java que JVM inició por primera vez en el lanzamiento de una aplicación y continúa ejecutándose hasta que el usuario elige cerrarlo o encuentra una excepción no controlada.
Ahora, el punto a tener en cuenta aquí es que aunque el hilo principal es el hilo de Java, sigue escuchando los eventos del usuario y dibuja cuadros de 60 fps en la pantalla y aún así no morirá después de cada ciclo. como es asi
Los subprocesos por defecto no tienen un bucle de mensajes asociado, pero puede asignar uno llamando a Looper.prepare () en el método de ejecución y luego llamando a Looper.loop ().
Si desea profundizar en cómo Looper gestiona la
Message
cola de objetos, puede echar un vistazo al código fuente deLooperclass
:A continuación se muestra un ejemplo de cómo puede crear una clase
Looper Thread
y comunicarse con ellaActivity
utilizandoLocalBroadcast
Uso :
¿Podemos utilizar la tarea Async o los servicios de intención en su lugar?
Las tareas asíncronas están diseñadas para realizar una operación corta en segundo plano y proporcionar progreso y resultados en el hilo de la interfaz de usuario. Las tareas asíncronas tienen límites, como no puede crear más de 128 tareas asíncronas y
ThreadPoolExecutor
solo permitirá hasta 5 tareas asíncronas .IntentServices
también están diseñados para realizar tareas en segundo plano durante un poco más de tiempo y puede usarLocalBroadcast
para comunicarseActivity
. Pero los servicios se destruyen después de la ejecución de la tarea. Si desea mantenerlo funcionando durante mucho tiempo, entonces necesita hacer diablos comowhile(true){...}
.Otros casos de uso significativos para Looper Thread:
Se utiliza para la comunicación de socket de 2 vías donde el servidor sigue escuchando el socket del cliente y confirma el acuse de recibo
Procesamiento de mapa de bits en segundo plano. Pase la url de la imagen al hilo Looper y aplicará efectos de filtro y la almacenará en una ubicación temporal y luego transmitirá la ruta temporal de la imagen.
fuente
Esta respuesta no tiene nada que ver con la pregunta, pero el uso de looper y la forma en que las personas crearon el controlador y el looper en TODAS las respuestas aquí son simplemente una mala práctica (aunque algunas explicaciones son correctas), tengo que publicar esto:
y para una implementación completa
fuente
Manejar múltiples elementos hacia abajo o subir en un Servicio es un mejor ejemplo.
Handler
y aAsnycTask
menudo se usan para propagar Eventos / Mensajes entre la UI (hilo) y un hilo de trabajo o para retrasar acciones. Por lo tanto, están más relacionados con la interfaz de usuario.A
Looper
maneja tareas ( Runnables, Futures ) en una cola relacionada con subprocesos en segundo plano, incluso sin interacción del usuario o una IU mostrada (la aplicación descarga un archivo en segundo plano durante una llamada).fuente
DE DOCUMENTOS
Looper
Looper
Clase utilizada para ejecutar un bucle de mensajes para athread
. Los subprocesos por defecto no tienen un bucle de mensaje asociado con ellos; para crear uno, llameprepare()
al hilo que ejecutará el bucle y luego hagaloop()
que procese los mensajes hasta que se detenga.Looper
es un ciclo de manejo de mensajes:MessageQueue
, que contiene una lista de mensajes. Un personaje importante de Looper es que está asociado con el hilo dentro del cual se crea el Looper.Looper
llama así porque implementa el bucle: toma la siguiente tarea, la ejecuta, luego toma la siguiente y así sucesivamente. ElHandler
se llama controlador porque alguien no podría inventar un nombre mejorLooper
es una clase Java dentro de la interfaz de usuario de Android que, junto con la clase Handler, procesa eventos de IU, como clics de botones, redibujos de pantalla e interruptores de orientación.Un hilo consigue un
Looper
yMessageQueue
llamandoLooper.prepare()
después de su ejecución.Looper.prepare()
identifica el hilo de llamada, crea un Looper y unMessageQueue
objeto y asocia el hiloCÓDIGO DE MUESTRA
Para obtener más información, consulte la siguiente publicación
fuente