Aunque las AsyncTask han sido marcadas como obsoletas en la versión R de android, para algunas operaciones de pocos segundos de duración, pueden todavía resultar útiles. Además hay mucho código basado en ellas que hay que mantener, entender y/o corregir, por lo que en este artículo mostramos las características básicas de esta técnicapara lanzar una tarea (thread) de manera asincrona que permita interactuar con el UI thread y ser cancelada desde éste. ( no es un marco de procesamiento paralelo en si mismo)
AsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes. It also has inconsistent behavior on different versions of the platform, swallows exceptions from
AsyncTask Android DevelpersdoInBackground
, and does not provide much utility over usingExecutor
s directly.
AsyncTask is designed to be a helper class aroundThread
andHandler
and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by thejava.util.concurrent
package such asExecutor
,ThreadPoolExecutor
andFutureTask
.
AsyncTask habilita el uso fácil y correcto del UI Thread. Es decir, permite dividir el trabajo entre el Background Thread y el UI Thread.
Permite realizar “operaciones pesadas” en background threads y publicar los resultados en el UI Thread sin necesisad de declarar ni manipular Threads o Handlers.
El Background Thread realiza la “operación pesada” y opcionalmente puede reportar su progreso.
El UI Thread, a través del AsyncTask es responsable de:
- La configuración de la “operación pesada”
- La publicación del progreso cuando éste sea reportado
- Completar la operación tras la finalización del Background Thread
El Background Thread, a través del AsyncTask es responsable de:
- Realizar el trabajo
- Comunicar opcionalmente el avance del trabajo
AsyncTask es una clase genérica que tiene tres parámetros
- Params: Tipo de datos de los parámetros de entrada al AsyncTask. Es el tipo usado en el Background Thread
- Progress: Tipo de datos usados para informar del progreso
- Result: Tipo de datos del resultado que procesará el AsyncTask
class AsyncTask<Params, Progress, Result> { .... }
AsyncTask Workflow
El método onPreExecute se ejecuta en el UI Thread antes de que arranque el método doInBackground
El método onPreExecute normalmente configura la “operación pesada”
El método doInBackground realiza la “operación pesada”.
Recibe una lista variable de parámetros de entrada y devuelve un resultado de tipo <Result>.
Durante su ejecución puede opcionalmente llamar al método publishProgress, pasándole una lista de valores que indicarán sobre el progreso de la “operación pesada”
Si el Background Thread llama a publishProgress, entonces se debe utilizar el callback onProgreshUpdate en el UI Thread mientras el Background Thread siga ejecutando.
Finalmente el callback onPostExecute es llamado en el UI Thread con el resultado proporcionado por el Background Thread.
Cancelar un AsyncTask es posible vía la llamada al método cancel(). En cualquier momento se puede llamar desde el UI Thread al método cancel() del AsyncTask.
Esto ocasiona que las siguientes llamadas al método isCancelled() devuelvan true.
Si permitimos la cancelación de la tarea deberemos preguntar por isCancelled() durante la ejecución de la “operación pesada”
Cuando la “operación pesada” termine le llamará a onCancelled(Object) en vez de a onPostExecute(Object)
Si no queremos que el usuario pueda interactuar con el UI Task mientras se ejecuta la “operación pesada” podemos hacer uso de un ProgressDialog.
En el ejercicio ThreadingAsyncTask tenéis un ejemplo completo de cómo utilizar el AsyncTask, como continuación del ejercicio Threading Simple