En el desarrollo de aplicaciones Android, es común que necesitemos realizar tareas que pueden llevar tiempo, como descargar datos de la web, procesar imágenes o realizar cálculos complejos. Ejecutar estas tareas en el hilo principal puede hacer que la aplicación se vuelva lenta o incluso se bloquee. Para evitar esto, Android proporciona varias formas de manejar tareas en segundo plano.
Conceptos Clave
- Hilos (Threads): La forma más básica de ejecutar tareas en segundo plano.
- AsyncTask: Una clase que facilita la ejecución de tareas en segundo plano y la actualización de la interfaz de usuario.
- WorkManager: Una API más moderna y robusta para manejar tareas en segundo plano que necesitan ser ejecutadas de manera confiable.
- JobScheduler: Una API para programar tareas que deben ejecutarse en momentos específicos o bajo ciertas condiciones.
Hilos (Threads)
Ejemplo Básico
new Thread(new Runnable() {
@Override
public void run() {
// Código que se ejecutará en segundo plano
// Por ejemplo, descargar datos de una URL
String data = downloadDataFromUrl("https://example.com/data");
// Actualizar la interfaz de usuario
runOnUiThread(new Runnable() {
@Override
public void run() {
// Código para actualizar la UI
textView.setText(data);
}
});
}
}).start();Explicación
- new Thread(new Runnable() { ... }).start();: Crea y empieza un nuevo hilo.
- runOnUiThread(new Runnable() { ... });: Permite actualizar la interfaz de usuario desde el hilo principal.
AsyncTask
Ejemplo Básico
private class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
// Código que se ejecutará en segundo plano
return downloadDataFromUrl(urls[0]);
}
@Override
protected void onPostExecute(String result) {
// Código para actualizar la UI
textView.setText(result);
}
}
// Ejecutar la tarea
new DownloadTask().execute("https://example.com/data");Explicación
- doInBackground(String... urls): Método donde se ejecuta la tarea en segundo plano.
- onPostExecute(String result): Método que se ejecuta en el hilo principal después de que
doInBackgroundha terminado.
WorkManager
Ejemplo Básico
- Dependencia en build.gradle
- Definir una clase Worker
public class DownloadWorker extends Worker {
public DownloadWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Result doWork() {
// Código que se ejecutará en segundo plano
String data = downloadDataFromUrl("https://example.com/data");
// Guardar los datos en Data para pasarlos a la UI
Data outputData = new Data.Builder()
.putString("data", data)
.build();
return Result.success(outputData);
}
}- Programar la tarea
WorkRequest downloadWorkRequest = new OneTimeWorkRequest.Builder(DownloadWorker.class).build(); WorkManager.getInstance(context).enqueue(downloadWorkRequest);
- Obtener el resultado
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorkRequest.getId())
.observe(this, workInfo -> {
if (workInfo != null && workInfo.getState().isFinished()) {
String data = workInfo.getOutputData().getString("data");
textView.setText(data);
}
});Explicación
- Worker: Clase que define la tarea en segundo plano.
- WorkRequest: Objeto que programa la tarea.
- WorkManager: API que gestiona la ejecución de la tarea.
JobScheduler
Ejemplo Básico
- Definir un JobService
public class DownloadJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
new Thread(new Runnable() {
@Override
public void run() {
// Código que se ejecutará en segundo plano
String data = downloadDataFromUrl("https://example.com/data");
// Actualizar la interfaz de usuario
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(data);
}
});
// Indicar que el trabajo ha terminado
jobFinished(params, false);
}
}).start();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}- Programar el trabajo
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(this, DownloadJobService.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
jobScheduler.schedule(jobInfo);Explicación
- JobService: Clase que define la tarea en segundo plano.
- JobScheduler: API que programa y gestiona la ejecución de la tarea.
Ejercicio Práctico
Ejercicio
- Crea una aplicación que descargue datos de una URL en segundo plano y los muestre en un
TextView. - Implementa la descarga usando
WorkManager.
Solución
- Dependencia en build.gradle
- Definir la clase Worker
public class DownloadWorker extends Worker {
public DownloadWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Result doWork() {
String data = downloadDataFromUrl("https://example.com/data");
Data outputData = new Data.Builder()
.putString("data", data)
.build();
return Result.success(outputData);
}
}- Programar la tarea
WorkRequest downloadWorkRequest = new OneTimeWorkRequest.Builder(DownloadWorker.class).build(); WorkManager.getInstance(context).enqueue(downloadWorkRequest);
- Obtener el resultado
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorkRequest.getId())
.observe(this, workInfo -> {
if (workInfo != null && workInfo.getState().isFinished()) {
String data = workInfo.getOutputData().getString("data");
textView.setText(data);
}
});Conclusión
En esta sección, hemos aprendido cómo manejar tareas en segundo plano en Android utilizando diferentes enfoques como Hilos, AsyncTask, WorkManager y JobScheduler. Cada método tiene sus propias ventajas y desventajas, y la elección del método adecuado dependerá de los requisitos específicos de tu aplicación. Con estos conocimientos, estarás mejor preparado para crear aplicaciones Android eficientes y responsivas.
Curso de Android Studio
Módulo 1: Introducción a Android Studio
- Introducción a Android Studio
- Configuración de Android Studio
- Entendiendo la interfaz de Android Studio
- Creando tu primer proyecto Android
Módulo 2: Desarrollo básico de Android
- Entendiendo la estructura del proyecto Android
- Introducción a los diseños XML
- Componentes básicos de la interfaz de usuario
- Introducción a las actividades
- Ejecutando tu aplicación en un emulador
Módulo 3: Desarrollo intermedio de Android
- Introducción a los Intents
- Trabajando con Fragmentos
- Manejo de la entrada del usuario
- Usando RecyclerView
- Redes en Android
Módulo 4: Desarrollo avanzado de Android
- Persistencia de datos con SQLite
- Usando Room para la gestión de bases de datos
- Componentes avanzados de la interfaz de usuario
- Vistas personalizadas y Canvas
- Trabajando con tareas en segundo plano
Módulo 5: Desarrollo profesional de Android
- Implementando la arquitectura MVVM
- Inyección de dependencias con Dagger
- Pruebas unitarias y pruebas de interfaz de usuario
- Publicando tu aplicación en Google Play
- Optimización del rendimiento
