Skip to content
Thread y Handler

Multitarea en Android con clases AsyncTask, Thread, Handler y Runnable

En esta publicación vamos a conocer las principales características de las clases AsyncTask, Handler, Thread y Runnable que nos permiten implementar tareas en segundo plano en una Aplicación Android. Al final, encontrarás también un cuadro comparativo donde vemos las situaciones donde se recomienda el uso de AsyncTask o de Threads.

Como explicamos en la introducción a las tareas en background, cualquier componente de Android, como puede ser una Activity, se ejecuta en el hilo principal o main thread (UIThread).

Si bien es cierto, que para operaciones rápidas no se encontrará ningún problema, es probable que necesitemos realizar procesos más costosos, y por lo tanto el hilo principal, encargado de mostrar la interfaz de usuario, quedaría bloqueado, con la consiguiente lentitud de cara al usuario. Es aquí donde interviene el sistema operativo Android, monitorizando todos los procesos que están en ejecución, y forzando a salir de la aplicación a aquellos que superen los 5 segundos.

Para evitar este tipo de situaciones, Android proporciona una serie de clases, que permiten trabajar en segundo plano, para aquellas operaciones que necesiten un mayor tiempo para ser procesadas. Vamos a describirlas a continuación:

AsyncTask

Clase que permite comunicarse con el subproceso del hilo de interfaz de usuario o hilo principal. Para ello realiza operaciones en segundo plano, mostrando los resultados en subprocesos de la interfaz de usuario.

Características principales de la clase AsyncTask:

  • Proporciona un mayor control y orden en la ejecución de nuestros procesos en segundo plano.
  • Marco de trabajo para operaciones no muy costosas.
  • Las tareas se ejecutan en un sólo hilo, para evitar errores derivados de ejecuciones en paralelo.
  • Tarea asíncrona definida en 4 pasos: ( OnPreExecute(), doInBackground(Params...), OnProgressUpdate(Progress...)  y   onPostExecute(Result...)
  • Se añadió a partir de la versión Honeycomb (API nivel 3, versión Android 3.0). Aquí, puedes consultar la documentación oficial de la clase AsyncTask

AsynTask

Implementación de Asyntask

A nivel de implementación, se deberá heredar de la clase Asynctask, donde se definen tres tipos genéricos:

public class TareaAsyncTask extends AsyncTask<params, progress, result>{
  • Params: Tipo de parámetro que se recibirá como entrada para la tarea en el método doInBackground(Params).
  • Progress: Parámetros para actualizar el hilo principal o UIThread.
  • Result: Es el resultado devuelto por el procesamiento en segundo plano.

Además de los tipos genéricos comentados anteriormente, será necesario sobreescribir los siguientes métodos para procesar y devolver la información tratada en segundo plano:

  • OnPreExecute(): Método llamado antes de iniciar el procesamiento en segundo plano.
  • doInBackground(Params...): En este método se define el código que se ejecutará en segundo plano. Recibe como parámetros los declarados al llamar al método execute(Params).
  • OnProgressUpdate(Progress...): Este método es llamado por publishProgress(), dentro de doInBackground(Params) (su uso es muy común para por ejemplo actualizar el porcentaje de un componente ProgressBar).
  • onPostExecute(Result...): Este método es llamado tras finalizar doInBackground(Params). Recibe como parámetro el resultado devuelto por doInBackground(Params).
  • OnCancelled(): Se ejecutará cuando se cancele la ejecución de la tarea antes de su finalización normal.

 

Thread

clase que proporciona su propia unidad concurrente de ejecución, y se puede definir como la unidad de procesamiento más pequeña que puede ser planificada por un sistema operativo. Una de sus principales características es permitir a una aplicación realizar varias tareas de manera simultánea. Define sus propios argumentos, variables y pila de llamada a métodos.

Formas de ejecutar un hilo:

  • Heredando (extends) de la clase base Thread y creando una instancia de dicha clase.
  • Implementando (implements) la interfaz Runnable, y creando una instancia de la clase que implementa dicha interfaz. Esta opción es muy útil cuando no es posible heredar de la clase base Thread.

Nota: Ambas formas deben realizar la llamada al método start(), para procesar el código situado en el método run().

Características principales de la clase Thread:

  • Ejecución de tareas en paralelo o de manera concurrente.
  • Los hilos de ejecución comparten el espacio de memoria.
  • El conjunto de hilos en ejecución que comparten los mismos recursos es conocido como un proceso.
  • Cualquier modificación de un dato en memoria, por parte de un hilo, permite el acceso al dato modificado para el resto de hilos de manera inmediata.
  • Cada hilo presenta de manera propia el contador de programa, la pila de ejecución (o pila de llamadas, que consiste en una estructura dinámica de datos, en las que el último proceso en entrar será el primero en salir, o lo que es lo mismo, el último proceso se ejecutará primero) y el estado de la CPU.
  • Un proceso seguirá en ejecución si al menos uno de sus hilos de ejecución sigue activo. Si un proceso finaliza, todos sus hilos de ejecución también lo harán.
  • Añadida a partir de la API nivel 1, puedes encontrar aquí la documentación oficial de la clase Thread

Ciclo vida de un Thread

Implementación de Thread

Se instancia la clase Thread, posteriormente se implementa el método run(), dónde se definirá el código a ejecutar cuando la instancia creada llame al método start().

Handler

Es aquella que permite manejar y procesar mensajes, proporcionando un mecanismo para su envío (a modo de puente) entre threads o hilos, y así poder enviar mensajes desde nuestro hilo secundario al UIThread o hilo principal.

Características principales de la clase Handler:

  • Permiten poner en cola una acción que se realiza en un subproceso distinto al suyo.
  • Cada instancia de la clase Handler está asociada a un sólo hilo y a la cola de mensajes de este.
  • Comunicación del hilo secundario con el hilo principal o UIThread a través de un controlador.
  • Proporciona varios métodos para poner en cola un mensaje en la parte delantera o enviar al final de la cola después de un determinado tiempo ( sendMessageAtFrontOfQueue(Message msg)  y   sendMessageAtTime(Message msg, long uptimeMillis) )
  • Añadida a partir de la API nivel 1, puedes consultar aquí la documentación oficial de la clase Handler

Thread y Handler

Implementación de Handler

Se instancia la clase Handler, para posteriormente llamar al método sendMessage(), encargado de avisar al UIThread para realizar las tareas de repintado incluidas en el método handleMessage(Message msg).

Runnable

Clase que representa un comando que puede ser ejecutado. Es muy común su uso para la ejecución de código en un hilo diferente.

Dicha clase implementa el método run(), que será llamado cuando un hilo es iniciado y creado dentro de una clase que implemente la interfaz Runnable.

Implementación de Runnable

Bastará con implementar la clase Runnable, y añadir el método run() (tras implementar la clase Runnable, nos indicará un error, y sólo deberemos posicionarnos sobre él y pulsar las teclas Alt + Enter y seleccionar la opción «Implement Methods», seleccionando el método a implementar, en nuestro caso el método run()):

Aquí puedes consultar la documentación oficial de la clase Runnable

AsyncTask vs Thread

Para finalizar esta presentación de las clases que nos permiten implementar tareas en segundo plano en Android, vamos a comprender las situaciones en las que se recomienda el uso de la clase AsyncTask o la clase Thread, dependiendo de las necesidades del proyecto:

 

Uso de AsynTask Uso de Threads
  • En operaciones de red que no requieran la descarga de grandes cantidades de datos.
  • Tareas sobre disco que no tomen más de algunos segundos.
  • En tareas cuyo resultado del procesamiento en segundo plano vaya a ser publicado en el subproceso del hilo de la interfaz de usuario.
  • No es necesario el uso de Handler.
  • En operaciones de red, ya sea de carga o descarga, con una moderada o alta cantidad de datos.
  • En tareas de gran consumo de CPU que deban ejecutarse en segundo plano.
  • En tareas que sea necesario controlar el consumo de CPU por parte del hilo gráfico a GUI (graphical user interface).
  • En tareas que deseemos controlar la prioridad de ejecución (cola de procesamiento).
  • No interacciona con el hilo de interfaz de usuario, siempre y cuando, el ciclo de vida de la aplicación no esté destinada a ejecutarse en segundo plano.

 

En la próxima publicación veremos un proyecto ejemplo donde gestionaremos varios hilos en segundo plano mediante el uso de la clase AsyncTask.

Volver arriba
Esta web usa cookies para su correcto funcionamiento. No hay cookies de publicidad, aunque algunos de los contenidos mostrados (videos o documentos insertados) están alojados en servicios externos (Youtube, Vimeo, Box...) que sí pueden implementar sus propias cookies. También se ha incluido en pruebas un Agente AI que incluye sus propias cookies   
Privacidad