miércoles, 16 de mayo de 2012

Asynctask en Android

Una de las "consideraciones" relativamente nuevas del sistema operativo Android Ice Cream Sandwich, que es el más nuevo hasta la fecha que estoy escribiendo esta entrada y en el cual estoy haciendo mi aplicación, es que no puedes hacer una conexión a un servidor en una sola tarea principal, por lo que es necesario crear tareas adicionales en la actividad para poder hacer esta conexión, algo que por ejmplo en los sistemas operativos Android, versiones 2.X.X, no tienen, por lo que estuve investigando como poder hacer este tipo de conexión en mi app y encontré que podemos hacer tareas en el fondo en la aplicación, en esta entrada hablaré de como puedes hacer ese tipo de tareas.


Clase AsyncTask

Cuando estamos desarrollando una aplicación de Android, podemos disponer de alguna tarea se pueda ejecutar en segundo plano, pero que pasa si solamente queremos hacer una tarea sencilla en el fondo, para eso podemos utilizar esta clase AsyncTask.

Nuestra aplicación de Android puede llegar a ser compleja de manera que estemos desarrollando con el tiempo, por lo que, si tenemos una conexión con un servidor o enviar y recibir datos desde la Web, como lo es en mi aplicación, se ha vuelto obligatorio en las últimas versiones que esto se haga sin interrumpir el hilo de la interfaz de usuario, si deseas hacer esto, te lanzará errores que no estña permitiendo hacerlo.

En primer lugar vamos a definir, ¿Cuál es el hilo de la interfaz de usuario?, bueno pues este es el que regulamente es el principal en nuestra aplicación, esto quiere decir que es en donde todo se procesa para inciar la aplicación, es como tener una sola tarea que hace todo lo importante, entonces, si solo tuvieramos que hacer una interfaz de usuario, en donde solamente mostramos botoncitos y hace funciones sencillas, esto está bien, pero si tu no estás en ese caso, entonces podemos tener múltiples hilos que se ejecutan al mismo tiempo, en una sola aplicación, el hilo de la interfaz de usuario, que nos permite movernos a través de la pantalla, mientras que por ejemplo, en una tarea de segundo plano, estamos recibiendo datos desde un servidor.

¿Cómo podemos hacer esto? Pues, existen muchas maneras, según yo, por ejemplo usuando Threads de java, hacer Runnables, etc..., pero considero que esta es una manera mucho más sencilla y mejor que las demás, utilizando la clase AsyncTask.

Una estructura típica de una clase de AsyncTask es la siguiente:


private class miTarea extends AsyncTask<x, y, z>

protected void onPreExecute(){

}


En donde podemos ver que onPreExecute() se ejecuta antes de empezar un nuevo hilo, no tiene valores de entrada ni de salida, así que aquí podemos inicializar las varibles o lo que querramos hacer.

 
protected Z doInBackground(X...x){

}


En este método, podemos decir que es el más importante de la clase AsyncTask, es en donde podemos poner todo lo que queremos que se haga en el fondo de la aplicación, en un hilo diferente al principal, aquí la entrada es un conjunto de objetos x, en donde como podemos ver en la cabecera, son los que los que le entran a la extends de AsyncTask, devolviendo un objeto Z.


protected void onProgressUpdate(Y y){

}


 Este método es el que se llama cuando se utiliza otro método llamado publishProgress(y), en donde por lo general se utiliza cuando queremos mostrar algún progreso o información en pantalla principal, al igual que una barra de progreso, mostrando la operación que se está haciendo en el fondo.


protected void onPostExecute(Z z){

}


Este método es utilizado cuando después de toda la operación que se hizo en background, lo manda llamar, y le entra como parámentro de entrada, el parámetro de salida del método de doInBackground.

Entonces podemos decir que los valores que entran a la AsyncTask son X que es el tipo de variable de entrada que tenemos para el proceso del fondo.

La Y es el tipo de objetos que se van a introducir en el método onProgressUpdate, y la Z es el tipo de objetos que tendremos del resultado de las operaciones hechas en doIbBackground.

Para hacer llamar esta tarea lo que tenemos que hacer es:

 
miTarea tareita = new miTarea();

tareita.execute(x);


En donde x es la entrada del parametro del tipo X.

Podemos que, una vez que se esté ejecutando, saber el estatus, con el siguiente método.

tareita.getStatus();

en donde podemos tener resultados:
  • Running: Indicando que la tarea se está ejecutando
  • Pending: Indicando que la tarea no se está ejecutando
  • Finished: Indicando que onPostExecute(); ha terminado.


Consejos

Estos consejos les pudieran ayudar al momento de realizar una AsyncTask.
  • No debes de llamar a los métodos de onPreExecute, doInBackground, y onPostExecute manualmente, ya que estos se realizan automáticamente por el sistema.
  • No se puede llamar un AsyncTask anidado o dentro de otro AsyncTask. 
  • La llamada a un método de ejecución debe de realizarce desde el hilo de la interfaz de usuario.
  • Los parámetros de entrada de la tarea pueden ser arrays de objetos, de esta manera podemos poner cualquier objeto que querramos.

Referencias

Usando efectivamente AsyncTask
Class Overview

2 comentarios:

  1. Corroboro el "No puedes llamar un AsyncTask dentro de otro".

    De pronto mi App dejó de funcionar cuando sobrecargué un método heredado que accedía a internet (en la sobrecarga hacía una llamada a un AsyncTask).

    La cosa es que en algún momento se anidaban y la app se quedaba congelada... jajajaja.

    Gracias!

    ResponderEliminar