Para las operaciones complejas dentro de una app es habitual
el empleo de multiproceso, de forma que la aplicación no quede bloqueada
mientras se efectúan dichas tareas.
En Android existen diversas formas para implementarlo, por
ejemplo se pueden emplear Threads Java, pero tiene una serie de implicaciones
con el acceso a componentes del interfaz gráfico que dificulta su gestión.
En Android se pueden emplear las
AsyncTask, que representan una forma sencilla de crear procesos independientes,
aislando al programador del uso de Threads. Para poder emplear una tarea de
esta forma es necesario definir una clase que herede de la clase AsyncTask y
sobreescribir los métodos correspondientes.
Compatibilidad
v3
Lo mínimo necesario
El método principal es
doInBackground, y es el único que hay que sobrescribir obligatoriamente. En el
siguiente código se crea una clase privada dentro del Activity para utilizar la
AsyncTask:
public class MainActivity extends Activity {
/**
* Los parámetros de la clase indican
* Object tipo del array de entrada
* Integer tipo para incremento de progreso
(no se usa en este caso)
* String tipo devuelto por doInBackground
(no se usa en este caso)
*/
private class Tarea extends AsyncTask<Object, Integer, String>{
@Override
protected String doInBackground(Object... arg0) {
try {
Thread.sleep(1000);
} catch
(InterruptedException e) {
;
}
return "Finalizado";
}
}
...
|
Para ejecutar la tarea
simplemente se crea una instancia de esta clase y se invoca al método execute.
El parámetro del método execute es el array de Object que en este caso recibe
el método doInBackground (es posible no pasar ningún parámetro).
Tarea tarea = new Tarea();
tarea.execute();
|
Como se ha comentado, el método
doInBackground se encarga de ejecutar un proceso independiente. Es necesario
tener precaución ya que este método no podrá acceder a los componentes del
interfaz gráfico, pero AsyncTask posee otros métodos para solucionar este
aspecto, onPreExecute se ejecuta antes de doInBackground y puede emplearse para
inicializar elementos del interfaz, mientras que onPostExecute se ejecutará al
finalizar la tarea y recibe el resultado producido en doInBackground.
/**
* Los parámetros de la clase
indican
* Object tipo del array de entrada
* Integer tipo para incremento de
progreso (no se usa en este caso)
* String tipo devuelto por doInBackground
y recibido por onPostExecute
*/
private class Tarea extends AsyncTask<Object, Integer,
String>{
@Override
protected void onPreExecute(){
TextView tv =
(TextView) findViewById(R.id.tvText);
tv.setText("Iniciado");
}
@Override
protected String doInBackground(Object... arg0) {
try {
Thread.sleep(1000);
} catch
(InterruptedException e) {
;
}
return "Finalizado";
}
@Override
protected void onPostExecute(String result){
TextView tv =
(TextView) findViewById(R.id.tvText);
tv.setText(result);
}
}
|
ProgressDialog
Las AsyncTask además facilitan la
gestión de diálogos de progreso asociados al proceso en ejecución. El método
onProgressUpdate se encargaría de la actualización del progreso de un diálogo
de progreso definido.
Cuando la tarea no tiene una
duración determinada se emplea un diálogo infinito muy habitual en Android, y
se mostrará y ocultará gestionándolo desde los métodos correspondientes del
AsyncTask:
private class Tarea extends AsyncTask<Object, Integer, String>{
private
ProgressDialog dialog;
@Override
protected void onPreExecute(){
dialog =
ProgressDialog.show(getActivity(),
getString(R.string.app_name), getString(R.string.buscando), true);
...
}
@Override
protected String doInBackground(Object... arg0) {
...
}
@Override
protected void onPostExecute(String result){
dialog.dismiss();
...
}
}
|
Cancelar diálogos
El método onCancelled de un
AsyncTask se ejecuta automáticamente cuando la tarea se interrumpe a través del
método cancel, y se encargará de cancelar los procesamientos que se encontraran
en curso y dejar a la app en un estado estable. El método cancel puede ser
invocado al pulsar un elemento del interfaz o al pulsar el botón atrás,
quedando la tarea interrumpida.
En el siguiente código se
aprovecha el método onCancel del diálogo de progreso (lanzado al pulsar back)
para detener la tarea:
@Override
protected void onPreExecute()
{
dialog =
ProgressDialog.show(getActivity(),
getString(R.string.app_name), getString(R.string.buscando), true);
dialog.setCancelable(true);
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void
onCancel(DialogInterface dialog) {
TareaEnvio.this.cancel(true);
}
});
}
@Override
protected void onCancelled() {
TextView
tv = (TextView) findViewById(R.id.tvText);
tv.setText("Cancelado");
}
|
No hay comentarios:
Publicar un comentario