lunes, 20 de julio de 2009

Ejecutar una ventana de cargando entre transiciones de pantallas

Enunciado:

Imaginemos que tenemos una pantalla o actividad A que llama a una actividad B. La actividad B a la hora de cargarse debe recoger datos de un servidor externo.

Sería recomendable por tanto, que a la hora de cargar los datos de dicho servidor, se mostrara una ventana de Cargando.

¿Cómo se hace?

Respuesta:

La ventana que muestra un cargando se llama ProgressDialog. Tras mostrar dicho dialog debes ejecutar la acción que quieras (por ejemplo, recoger datos de un servidor) en un thread aparte. Debido a que una vez que se recuperan los datos se debe cerrar la ventana e interactuar con la UI (para colocar los datos cargados, por ejemplo), no se puede hacer en la clase Thread, con lo que debemos utilizar un Handler (como el callback handler típico de las aplicaciones asíncronas - ajax, para los javascripteros).

Todo esto se resume en:

- Cargo la pantalla usando una funcion setupData:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.b);
setupData();
...
}

- Escribo el metodo setupData():


private void setupData() {
dialog=ProgressDialog.show(B.this, "",
"Loading. Please wait...", true);

new Thread() {
public void run() {
try{
new BService().doSomeWork(); // Toda la logica de negocio va aqui
getDataHandler.sendEmptyMessage(0);
} catch (Exception e) {
Log.e(getClass().getSimpleName(),"excepcion en thread",e);
}
}
}.start();
}

La variable dialog es una variable a nivel UI, de modo que la pueda referenciar desde el handler:

- Defino mi handler (getDataHandler, es decir, el que recoge los datos).

private Handler getDataHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
dialog.dismiss(); //cierro ventana
//hago lo que sea con el resultado del BService anterior
//Tambien podria mostrar unmensaje de error si ha existido error a la hora de recuperar datos
}
};

Eso es todo. La verdad es que da pie a crear una clase ProgressActivity que haga esto de por sí, y las actividades que quieras que tengan este comportamiento heredarían de esta actividad e implementarían las clases abstractas de hacerPre() -llamado en el Thread- y hacerPost() --llamado tras ejecutar el Thread-.

¿alguien se atreve? ;-)

3 comentarios:

erpolimix dijo...

Muy buen post, poco a poco somos más los androides

Andromede dijo...

Muy bueno, muchísimas gracias por compartir

Unknown dijo...

Amigo de pronto se puede montar a esta opción un boton de cancelar en caso de que el usuario ya no quiera accederer a la información del servidor???

Publicar un comentario