Android: ¿Cuándo debería usar un controlador () y cuándo debería usar un hilo?

Cuando necesito algo para ejecutar de forma asíncrona , como una tarea de larga ejecución o una lógica que usa la red, o por cualquier razón, iniciar un nuevo subproceso y ejecutarlo funciona bien. Crear un controlador y ejecutarlo también funciona. ¿Cual es la diferencia? ¿Cuándo debería usar cada uno? ¿Cuáles son las ventajas / razones para usar un Handler y no un Thread ?

PD. – Por el bien de esta pregunta, ignoremos AsyncTask . – Handler().postDelayed caso de uso Handler().postDelayed es claro para mí, por el bien de esta pregunta supongamos que necesito que la tarea comience de inmediato.

Si lo que estás haciendo es “pesado” deberías hacerlo en un hilo. Si no lo inicia explícitamente en su propio hilo, se ejecutará en el hilo principal (UI), que puede ser notorio por la inestabilidad o la lentitud de la interfaz de sus usuarios.

Curiosamente, cuando utiliza un hilo, a menudo es útil utilizar un controlador como medio de comunicación entre el hilo de trabajo que está iniciando y el hilo principal.

Una interacción típica de Thread / Handler podría verse más o menos así:

 Handler h = new Handler(){ @Override public void handleMessage(Message msg){ if(msg.what == 0){ updateUI(); }else{ showErrorDialog(); } } }; Thread t = new Thread() { @Override public void run(){ doSomeWork(); if(succeed){ //we can't update the UI from here so we'll signal our handler and it will do it for us. h.sendEmptyMessage(0); }else{ h.sendEmptyMessage(1); } } }; 

Sin embargo, en general, el hecho de llevar a casa es que debe usar un subproceso cada vez que esté haciendo un trabajo que podría ser de larga duración o muy intensivo (es decir, cualquier red, archivo IO, aritmático pesado, etc.).

Handler y Thread son realmente 2 cosas diferentes.

Se debe crear un hilo para ejecutar trabajos de larga ejecución.

Un controlador es un objeto muy conveniente para comunicarse entre 2 subprocesos (por ejemplo: un hilo de fondo necesita actualizar la interfaz de usuario. Puede usar un controlador para publicar algo ejecutable desde el hilo de fondo al hilo de la interfaz de usuario).

Entonces no tiene la opción entre Handler o Thread. ¡Usa un hilo para hacer trabajos pesados! (puede utilizar un controlador si su hilo de fondo activará algún trabajo en otro hilo, la mayoría de las veces el hilo de la interfaz de usuario)

Handler y Thread son dos cosas diferentes, pero no se contradicen entre sí. Puede tener un Handler y un Thread al mismo tiempo y en realidad cada controlador debe ejecutarse en un Thread .

Para obtener más detalles, es posible que desee ver este artículo .

enter image description here

Un controlador se ejecuta en el mismo Thread , un Thread ejecuta en un hilo diferente.

Use un controlador si necesita ejecutar algo en el mismo hilo , generalmente un elemento de GUI o algo así.

Use un hilo si desea mantener el hilo principal libre para hacer otras cosas . Úselo para cualquier cosa que lleve una cantidad significativa de tiempo.

Los manejadores son la mejor forma de comunicación entre el fondo y el hilo de UI. En general, los manipuladores están asociados con el mensaje Cola de un hilo y se usan para enviar mensajes y ejecutarlos en el mensaje.

UTILIZAR:

Subproceso: para realizar tareas en el subproceso saperate (fondo) que el subproceso de la interfaz de usuario. (ayuda a desbloquear el hilo de UI)

Manejador Se usa para comunicarse entre la interfaz de usuario y el hilo de fondo.

Eche un vistazo a este artículo

Si necesita actualizar la interfaz de usuario desde un nuevo subproceso, debe sincronizar con el subproceso de la interfaz de usuario.

Puede usar la clase android.os.Handler o la clase AsyncTasks para esto.

La clase Handler puede actualizar la interfaz de usuario. Un controlador proporciona métodos para recibir instancias del mensaje o clase ejecutable.

You thread puede publicar mensajes mediante el método sendMessage (Message msg) o mediante el método sendEmptyMessage ().

… más información aquí sobre hilos, etc. (incluye turoriales para los diferentes mecanismos de subprocesamiento y sincronización y cuándo usar qué)

¿Cuáles son las ventajas / razones para usar un controlador y no un hilo?

Un controlador le permite enviar y procesar mensajes y objetos Runnable asociados con MessageQueue un hilo. Cada instancia de Handler está asociada con un único hilo y la cola de mensajes de ese hilo.

Cuando crea un nuevo Handler , está vinculado a la fila / cola de mensajes del subproceso que lo está creando. A partir de ese momento, entregará los mensajes y los ejecutables a esa cola de mensajes y los ejecutará a medida que salgan del mensaje. cola.

Hay dos usos principales para un Manejador:

  1. Para progtwigr mensajes y Runnables para que se ejecuten como un punto en el futuro
  2. Para poner en cola una acción que se realizará en un hilo diferente al tuyo.

Si usa subprocesos de Java, debe manejar algo solo: sincronizar con el hilo principal, cancelar un hilo, etc.

Este único subproceso no crea un grupo de subprocesos a menos que utilice ThreadPoolExecutor o ExecutorService API.

(Toma esta consulta de tus comentarios en la respuesta de Blackbelt)

¿Por qué no usar un ejecutor? e incluso si quisiera usar un controlador para hacer eso, ¿cómo?

Referencia: artículo de ejecución de subprocesos

Hay ciertos tipos de trabajo que pueden reducirse a tareas altamente paralelas y distribuidas. Con el gran volumen de paquetes de trabajo que esto crea, AsyncTask y HandlerThread no son clases apropiadas. La naturaleza de subproceso único de AsyncTask convertiría todo el trabajo subprocesado en un sistema lineal. El uso de la clase HandlerThread , por otro lado, requeriría que el progtwigdor manejara manualmente el equilibrio de carga entre un grupo de hilos.

ThreadPoolExecutor es una clase auxiliar para facilitar este proceso. Esta clase gestiona la creación de un grupo de hilos, establece sus prioridades y gestiona cómo se distribuye el trabajo entre esos hilos. A medida que aumenta o disminuye la carga de trabajo, la clase crea o destruye más hilos para ajustarse a la carga de trabajo.

  BlockingQueue workQueue= new LinkedBlockingQueue(100); // Work pool size ThreadPoolExecutor executor = new ThreadPoolExecutor( Runtime.getRuntime().availableProcessors(), // Initial pool size Runtime.getRuntime().availableProcessors(), // Max pool size 1, // KEEP_ALIVE_TIME TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT workQueue); 

Puede consultar este artículo de la guía para desarrolladores en create-threadpool para obtener más detalles.

Eche un vistazo a esta publicación sobre el uso de Handler para ejecutar varias instancias de Runnable. En este caso, todas Runnable tareas Runnable se ejecutarán en un solo subproceso.

Android: brindis en un hilo

Handler se puede usar junto con Thread para crear un mecanismo en cola. Uou puede usar el handler para publicar algo en el Thread Looper