En este video te explicamos en detalle todo el proceso para publicar una Aplicación Android…
Ejemplo tareas en segundo plano en Android: Aplicación de descarga de ficheros (I)
3.
Ejemplo tareas en segundo plano en Android: Aplicación de descarga de ficheros (I)
Para este ejercicio práctico, utilizaremos las clases Thread, Handler y AsyncTask para realizar tareas en segundo plano, como pueden ser ver el funcionamiento de una barra de progreso o la descarga de una imagen.
La estructura de la aplicación estará formada por una clase MainActivity que heredará de Activity, donde se definirán los elementos visuales y eventos encargados de realizar las diferentes llamadas, para ejecutar tareas en background.
En esta clase además se implementa e instancia las tareas con Thread y Handler. También definiremos una clase llamada TareaAsyncTask, que heredará de la clase AsyncTask, encargada de realizar tareas menos costosas (se encargará de mostrar un componente ProgressDialog para descargar una imagen).
Nota: Dividiremos esta aplicación en dos publicaciones. En la 2ª de ellas, podrás como siempre descargar todo el código de la aplicación.
Esquema funcionamiento Thread + Handler
En el siguiente esquema, se describen los pasos realizados para la ejecución de tareas en segundo plano con el uso de las clases Thread y Handler:
- Pulsamos el botón «Arrancar Hilo + Handler».
- Mostrará que tarea se está ejecutando.
- Mensaje emergente indicando que la tarea ha sido lanzada.
- El componente ProgressBar comienza a mostrar el progreso de ejecución.
- Al llegar al 100%, mostrará un mensaje emergente indicando que la tarea ha finalizado, habilitando el botón «Reiniciar Barra de Progreso».
Esquema funcionamiento AsyncTask
En el siguiente esquema, se describen los pasos realizados para la ejecución de tareas en segundo plano con el uso de la clase AsyncTask:
- Pulsamos el botón «Arrancar AsyncTask».
- Mostrará que tarea se está ejecutando.
- Mensaje indicando que la tarea de descarga de archivo está en proceso.
- Se muestra la imagen descargada.
- Se habilita el botón «Detener AsyncTask», para detener la tarea y reiniciar el componente eliminando la imagen descargada.
A nivel de Layout será necesario añadir los siguientes elementos:
- Cuatro componentes de tipo Button encargados de lanzar o reiniciar/detener las tareas en segundo plano.
- Dos componentes de tipo TextView para mostrar la tarea lanzada y el estado de progreso de la misma.
- Además será necesario definir un componente de tipo ProgressBar para mostrar el progreso de la tarea lanzada, utilizando la clase Thread en conjunto con la clase Handler (esta última estará encargada de comunicar y refrescar la UIThread o hilo principal con los cambios).
- Se definirá, de manera programática, un componente ProgressDialog, cuya misión será la de mostrar la tarea de descarga de una imagen, mediante el uso de la clase AsyncTask (será necesario establecer permisos de Internet en el AndroidManifest.xml).
TareasSegundoPlano/src/com.academiaandroid.tareassegundoplano/MainActivity.java
- En primer lugar se enlazan los componentes con los recursos definidos a nivel de layout, dónde podemos destacar el uso del componente ProgressBar para mostrar una tarea en ejecución, y el componente ImageView, que inicialmente no mostrará ninguna imagen, para posteriormente mostrar la imagen descargada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[...] //Enlazamos los componentes con sus recursos a nivel de Layout, además //de establecer la lógica de visibilidad de los botones. tvTipoTarea = (TextView)findViewById(R.id.tvTipo); btnArrancarHilo = (Button)findViewById(R.id.btnArrancarHilo); btnReiniciar = (Button)findViewById(R.id.btnReiniciar); btnArrancarAsyncTask = (Button)findViewById(R.id.btnArrancarAsyncTask); btnDetenerAsyncTask = (Button)findViewById(R.id.btnDetenerAsyncTask); prgssTarea = (ProgressBar)findViewById(R.id.prgssTarea); imgAA = (ImageView)findViewById(R.id.imgAA); tvEstadoProgreso = (TextView)findViewById(R.id.tvEstadoProgreso); tvEstadoProgreso.setTextColor(Color.RED); tvTipoTarea.setTextColor(Color.RED); btnReiniciar.setVisibility(View.INVISIBLE); btnDetenerAsyncTask.setVisibility(View.INVISIBLE); [..] |
-
Posteriormente se define el evento encargado de controlar si el botón de ‘Arrancar AsyncTask‘ ha sido pulsado, para llamar al método ‘ execute() ‘, cuya misión es la de lanzar la ejecución de la tarea, recibiendo como parámetro la URL de la imagen a descargar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[..] //Evento que caza el cambio de estado del botón 'Arrancar AsyncTask', //mostrando que acción ha sido lanzada, y llamando al método 'execute()' //pasándole como parámetros la URL de la imagen a descargar. btnArrancarAsyncTask.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { tvTipoTarea.setTextColor(Color.RED); tvTipoTarea.setText(" AsyncTask"); tareasynctask = new TareaAsyncTask(MainActivity.this, imgAA); tareasynctask.execute ("https://dl.dropboxusercontent.com/u/67598004/LogoVertical_baja.png"); btnDetenerAsyncTask.setVisibility(View.VISIBLE); } }); [...] |
-
Otra de las opciones implementadas es poder refrescar el componente TextView encargado de mostrar el porcentaje de la tarea lanzada, mediante el uso de la clase Handler.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[...] //Método encargado de actualizar el porcentaje de la barra de progreso. private Handler handler = new Handler() { int prg = 0; @Override public void handleMessage(Message msg) { prg ++; prgssTarea.setProgress(prg); String porcentaje = String.valueOf(prg).toString(); tvEstadoProgreso.setTextColor(Color.RED); tvEstadoProgreso.setText(" " + porcentaje + "% completado"); if(porcentaje.equals("100")) { prg = 0; } } }; [...] |
-
Por último se define el método runThread() , encargado de lanzar un nuevo hilo de ejecución (al pulsar sobre el botón ‘Arrancar Hilo + Handler‘), cuya función principal será recorrer las 100 posiciones establecidas en la barra de progreso, actualizando la información del porcentaje por cada ciclo del bucle ‘for‘ implementado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[...] //Método donde se define la lógica de ejecución de un hilo, //simulando una barra de progreso realizando una tarea. private void runThread() { new Thread(){ public void run(){ runOnUiThread(new Runnable() { @Override public void run() { prgssTarea.setProgress(0); } }); for(int i=1; i<=100; i++) { tiempoTarea(); prgssTarea.post(new Runnable() { public void run() { handler.sendMessage(handler.obtainMessage()); } }); } runOnUiThread(new Runnable() { @Override public void run() { tvEstadoProgreso.setText("Finalizado"); btnReiniciar.setVisibility(View.VISIBLE); Toast.makeText(getApplicationContext(), "Tarea con hilos finalizada", Toast.LENGTH_LONG).show(); } }); } }.start(); [...] |
Continuamos este proyecto en la siguiente publicación. donde podrás descargar todo el código del mismo.