WorkManager es una biblioteca Android Jetpack diseñada para ejecutar tareas diferidas y en segundo plano con ejecución garantizada. A diferencia de Service o JobScheduler, WorkManager gestiona el ciclo de vida de la tarea: la reinicia en caso de fallo, se adapta a la versión de Android y tiene en cuenta las limitaciones del dispositivo. Según Android Developers, 2026, WorkManager es la solución preferida para la mayoría de las operaciones en segundo plano en el desarrollo moderno de Android.
Puntos clave
WorkManager es parte de Android Jetpack, una biblioteca para gestionar tareas en segundo plano que deben ejecutarse de forma garantizada, independientemente de si la aplicación está en primer plano o ha sido cerrada por el usuario. La biblioteca admite API 14+ y selecciona automáticamente el mecanismo de ejecución adecuado: JobScheduler en Android 5+, BroadcastReceiver + AlarmManager en versiones anteriores.
La característica clave de WorkManager es la ejecución garantizada. Si una tarea no se completó debido a un reinicio del dispositivo, cierre de la aplicación o fallo, WorkManager la reiniciará en la primera oportunidad. Esto hace que la biblioteca sea una opción ideal para tareas críticas de ejecución: envío de análisis, sincronización de bases de datos, carga de registros.
A diferencia de Background Service, WorkManager no requiere gestión de hilos ni del ciclo de vida. La biblioteca misma crea un grupo de hilos, maneja el Modo Doze, tiene en cuenta la versión de Android y proporciona una API unificada independientemente del nivel de API. El soporte para corrutinas y RxJava está disponible a través de CoroutineWorker y RxWorker respectivamente.
WorkManager proporciona soporte integrado para LiveData para rastrear el estado de las tareas. El método getWorkInfoByIdLiveData devuelve LiveData<WorkInfo> que se actualiza en cada cambio de estado: ENQUEUED, RUNNING, SUCCEEDED, FAILED, CANCELLED. Esto permite que los componentes de la UI reaccionen a los cambios sin sondeo manual del planificador y sin pérdidas de memoria gracias a los componentes Lifecycle-aware.
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(syncRequest.id)
.observe(viewLifecycleOwner) { workInfo ->
when (workInfo.state) {
WorkInfo.State.SUCCEEDED ->
showSuccess()
WorkInfo.State.FAILED ->
showError(workInfo.outputData)
else ->
showProgress()
}
}
La arquitectura de WorkManager se construye en torno a tres clases base: Worker, WorkRequest y WorkManager. Worker contiene la lógica de la tarea, WorkRequest describe los parámetros de ejecución y WorkManager gestiona la cola y la planificación. La biblioteca utiliza una base de datos Room interna para almacenar el estado de todas las tareas.
Worker es una clase abstracta con un único método doWork que se llama en un hilo en segundo plano. El método devuelve ListenableWorker.Result — SUCCESS, FAILURE o RETRY. WorkRequest vincula el Worker con los parámetros: tiempo de espera, etiqueta, retardo inicial y restricciones.
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
return try {
val api = RetrofitClient.api
val response = api.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
WorkManager planifica tareas de manera uniforme independientemente de la versión de Android. Al llamar a enqueue, la biblioteca guarda la tarea en Room, evalúa las condiciones actuales y selecciona el momento óptimo de ejecución. Internamente, puede usar JobScheduler, AlarmManager o su propio planificador — el desarrollador no tiene que preocuparse por ello.
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(15, TimeUnit.MINUTES)
.addTag("sync")
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
WorkManager admite dos tipos de solicitudes de ejecución: únicas y periódicas. La elección del tipo depende del escenario: la tarea debe ejecutarse una vez o repetirse en un intervalo determinado.
OneTimeWorkRequest está diseñado para tareas que deben ejecutarse una sola vez. Puede ser el envío de un registro, la sincronización de datos después de la autorización, la descarga de configuración en el primer inicio. El retardo se establece mediante setInitialDelay y las restricciones mediante setConstraints.
PeriodicWorkRequest es adecuado para tareas repetitivas con un intervalo mínimo de 15 minutos. La biblioteca garantiza que el intervalo entre ejecuciones no será menor al especificado, pero puede ser mayor debido a las limitaciones del dispositivo. Para tareas con una frecuencia inferior a 15 minutos, use Handler o Timer en Foreground Service.
| Parámetro | OneTimeWorkRequest | PeriodicWorkRequest |
|---|---|---|
| Frecuencia | única | repetida (mín. 15 min) |
| Cantidad | 1 ejecución | hasta cancelación |
| Retardo | setInitialDelay | setInitialDelay |
| Cadenas | soporta | no |
| Uso | descarga, sincronización | monitoreo, sondeo |
Las restricciones en WorkManager permiten establecer condiciones bajo las cuales se puede iniciar una tarea: conexión de red (NetworkType), nivel de batería (batteryNotLow), estado del almacenamiento (StorageNotLow) y modo inactivo (DeviceIdle). La tarea no se iniciará hasta que se cumplan todas las restricciones.
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<ImageUploadWorker>()
.setConstraints(constraints)
.build()
Las cadenas permiten organizar la ejecución secuencial o paralela de tareas. beginWith inicia una cadena, luego agrega el siguiente Worker que se ejecutará después de la finalización exitosa del anterior. Para la ejecución en paralelo, use workManager.enqueue(listOf(request1, request2)).
WorkManager.getInstance(context)
.beginWith(compressWorker)
.then(uploadWorker)
.then(cleanupWorker)
.enqueue()
// compress -> upload -> cleanup secuencialmente
JobScheduler se introdujo en Android 5 (API 21) como un servicio del sistema para planificar tareas en segundo plano. WorkManager vino a reemplazarlo, ofreciendo una API multiplataforma con migración automática y capacidades adicionales: cadenas, garantía de ejecución, etiquetas, observación de estado mediante LiveData.
Al migrar de JobScheduler a WorkManager, deberá convertir JobService en Worker, reemplazar JobInfo por WorkRequest y Context.getSystemService por la API de WorkManager. WorkManager maneja automáticamente los problemas de compatibilidad y maneja el Modo Doze de manera más correcta que una implementación manual de JobScheduler. Pasos de migración: 1) crear una clase Worker, 2) construir un WorkRequest con las mismas condiciones, 3) eliminar JobService y JobInfo del código y el manifiesto.
WorkManager admite el concepto de tareas únicas a través de ExistingWorkPolicy. Si ya existe una tarea con el nombre especificado, la política determina el comportamiento: KEEP (no crear una nueva), REPLACE (reemplazar la existente), APPEND (agregar al final de la cadena) y APPEND_OR_REPLACE. UniqueWorkRequest es conveniente para tareas que no deben duplicarse: sincronización de base de datos, descarga de configuración, envío de lotes de análisis.
WorkManager.getInstance(context)
.enqueueUniqueWork(
"sync_data",
ExistingWorkPolicy.KEEP,
syncRequest
)
CoroutineWorker admite el mecanismo setProgress, que permite pasar resultados intermedios de ejecución. Esto es útil para operaciones largas: descarga de archivos grandes, procesamiento por lotes de imágenes, migración de base de datos. La UI puede suscribirse a las actualizaciones a través de getWorkInfosByTagLiveData y mostrar el progreso en tiempo real. El método ForegroundInfo también está disponible para ejecutar un Worker como Foreground Service con una notificación si la tarea debe ser visible para el usuario.
class ProgressWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val total = 100
for (i in 1..total) {
setProgress(
workDataOf("progress" to i)
)
}
return Result.success()
}
}
WorkManager admite la transferencia de datos entre Workers a través de InputData y OutputData. InputData se crea durante la construcción de WorkRequest mediante Data.Builder y se pasa al Worker a través de inputData. Después de la ejecución, el Worker crea OutputData mediante workDataOf o Data.Builder y lo devuelve junto con Result.success(outputData). El siguiente Worker en la cadena recibe el outputData del anterior como su inputData. Los datos se almacenan en formato clave-valor con soporte para tipos básicos: String, Int, Long, Boolean, Double. El tamaño máximo de Data es 10 KB.
En la práctica, muchos proyectos utilizan WorkManager como el único planificador de tareas en segundo plano. Google recomienda migrar todos los JobService existentes a WorkManager, especialmente en aplicaciones que admiten Android 4.4 (API 19) e inferiores, donde JobScheduler no está disponible y WorkManager utiliza un mecanismo de respaldo a través de AlarmManager y BroadcastReceiver. Para pruebas, WorkManager proporciona TestListenableWorkerBuilder y TestWorkerBuilder, que permiten probar Workers en pruebas JUnit sin un planificador real.
Para probar WorkManager, use TestListenableWorkerBuilder de AndroidX Test, que permite ejecutar Workers en un entorno aislado y verificar el Result devuelto. La biblioteca proporciona soporte completo para JUnit y Robolectric para pruebas unitarias sin un planificador real. En general, WorkManager es adecuado para el 80% de las tareas donde antes se usaban Service o JobScheduler.
Preguntas frecuentes
Sí, WorkManager garantiza la ejecución incluso después de un reinicio. La biblioteca guarda todas las tareas incompletas en una base de datos Room y las restaura mediante BroadcastReceiver que se activa después del inicio del sistema.
Worker se ejecuta en un hilo en segundo plano sin soporte de corrutinas o RxJava. CoroutineWorker utiliza corrutinas de Kotlin con soporte para funciones suspend y cancelación mediante el ámbito de corrutina. RxWorker trabaja con Observable y Single, adecuado para cadenas reactivas.
Use workManager.cancelWorkById(id) o workManager.cancelAllWorkByTag("tag"). La biblioteca también proporciona el método cancelUniqueWork("name") para cancelar tareas únicas con el nombre especificado.
El intervalo mínimo para PeriodicWorkRequest es de 15 minutos. Esta limitación la establece Google para evitar un consumo excesivo de batería. Si una tarea debe ejecutarse con más frecuencia, use Foreground Service o Handler con un temporizador.
Sí, WorkManager admite API 14+. En dispositivos sin JobScheduler (inferior a API 21), la biblioteca utiliza una combinación de AlarmManager y BroadcastReceiver para la planificación de tareas. Esto hace que WorkManager sea una solución universal para tareas en segundo plano.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también