WorkManager te permite actualizar un WorkRequest
después de
se lo pusieron en cola. Esto suele ser necesario en las apps más grandes que cambian con frecuencia
restricciones o que necesiten actualizar a sus trabajadores sobre la marcha. A partir de WorkManager
versión 2.8.0, puedes hacerlo con la API de updateWork()
.
El método updateWork()
te permite cambiar ciertos aspectos de un
WorkRequest
sobre la marcha, sin tener que realizar el proceso de
cancelar y colocar en cola una nueva. Esto simplifica notablemente el proceso
el proceso de administración de recursos.
Evita cancelar trabajos
Por lo general, debes evitar cancelar una WorkRequest existente y colocar una nueva uno. Si lo haces, es posible que la app repita ciertas tareas para escribir una cantidad significativa de código adicional.
Considera los siguientes ejemplos en los que cancelar una WorkRequest puede causar dificultades:
- Solicitud de backend: Si cancelas una
Worker
mientras se procesa una carga útil para enviar al servidor, el nuevoWorker
debe volver a empezar y volver a procesar la carga útil potencialmente costosa. - Programación: Si cancelas un
PeriodicWorkRequest
y quieres como la nuevaPeriodicWorkRequest
para ejecutarse de acuerdo con la misma programación, necesitas para calcular una compensación horaria para garantizar que el nuevo tiempo de ejecución esté alineado con la solicitud de trabajo anterior.
La API de updateWork()
te permite actualizar las restricciones de una solicitud de trabajo y
otros parámetros sin la molestia de cancelar y poner en cola una nueva solicitud.
Cuándo cancelar el trabajo
Hay casos en los que debes cancelar directamente un WorkRequest
en lugar de
llama a updateWork()
. Esto es lo que debes hacer cuando quieras cambiar el
la naturaleza fundamental del trabajo que has puesto en cola.
Cuándo actualizar el trabajo
Imagina una app de fotos que hace una copia de seguridad diaria de las fotos del usuario. Tiene
puso en cola un PeriodicWorkRequest
para hacerlo. La WorkRequest
tiene restricciones
que requieran que el dispositivo se esté cargando y esté conectado a Wi-Fi.
Sin embargo, el usuario solo carga el dispositivo por 20 minutos diarios con un
cargador. En este caso, es posible que la app quiera actualizar WorkRequest
para relajar la
restricción de carga, para que pueda subir las fotos, incluso si el dispositivo
no está completamente cargada.
En este caso, puedes usar el método updateWork()
para actualizar el trabajo
las restricciones de la solicitud.
Cómo actualizar el trabajo
El método updateWork()
brinda un medio sencillo para actualizar un
WorkRequest
, sin tener que cancelar y poner en cola uno nuevo.
Para usar la actualización del trabajo en cola, sigue estos pasos:
- Obtener el ID existente para el trabajo en cola: Obtén el ID de la WorkRequest que
quieres actualizar. Puedes recuperar este ID con cualquiera de
getWorkInfo
, o si conservas manualmente el ID de la inicial WorkRequest para recuperación posterior con la propiedad públicaWorkRequest.id
, antes de colocarlo en la cola. - Crear una WorkRequest nueva: Crea un
WorkRequest
nuevo y usaWorkRequest.Builder.setID()
para establecer su ID de modo que coincida con el del dominioWorkRequest
- Establece restricciones: Usa
WorkRequest.Builder.setConstraints()
para pasar el Restricciones nuevas de WorkManager. - Llamar a updateWork: Pasa la nueva WorkRequest a
updateWork()
.
Ejemplo de actualización de trabajo
Este es un ejemplo de fragmento de código en Kotlin que demuestra cómo usar el
Método updateWork()
para cambiar las restricciones de batería de un WorkRequest
usado
Para subir fotos, sigue estos pasos:
suspend fun updatePhotoUploadWork() {
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve the work request ID. In this example, the work being updated is unique
// work so we can retrieve the ID using the unique work name.
val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
PHOTO_UPLOAD_WORK_NAME
).await()
val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return
// Update the constraints of the WorkRequest to not require a charging device.
val newConstraints = Constraints.Builder()
// Add other constraints as required here.
.setRequiresCharging(false)
.build()
// Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
val updatedWorkRequest: WorkRequest =
OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(newConstraints)
.setId(existingWorkRequestId)
.build()
// Pass the new WorkRequest to updateWork().
workManager.updateWork(updatedWorkRequest)
}
Cómo controlar el resultado
updateWork()
muestra un ListenableFuture<UpdateResult>
. El dado
UpdateResult
puede tener uno de los diversos valores que describen si es o no
WorkManager pudo aplicar tus cambios. También indica cuándo se pudo
para aplicar el cambio.
Para obtener más información, consulta los updateWork()
y UpdateResult
.
referencia.
Realiza un seguimiento del trabajo por generaciones
Cada vez que actualizas un WorkRequest
, su generación se incrementa en uno. Esta
te permite hacer un seguimiento exacto del WorkRequest
que está actualmente en cola.
Las generaciones te brindan más control cuando observas, rastreas y pruebas el trabajo
solicitudes.
Para obtener la generación de un WorkRequest
, sigue estos pasos:
- WorkInfo: Llama a
WorkManager.getWorkInfoById()
para recuperar una instancia. deWorkInfo
correspondientes a tuWorkRequest
.- Puedes llamar a uno de varios métodos que muestran un
WorkInfo
. Para ver más consulta la referencia de WorkManager.
- Puedes llamar a uno de varios métodos que muestran un
- getGeneration: Llama a
getGeneration()
en la instancia deWorkInfo
ElInt
que se muestra corresponde a la generación delWorkRequest
- Ten en cuenta que no hay un campo o una propiedad de generación, solo
WorkInfo.getGeneration()
.
- Ten en cuenta que no hay un campo o una propiedad de generación, solo
Ejemplo de generación de pistas
El siguiente es un ejemplo de implementación del flujo de trabajo descrito anteriormente para
y recupera la generación de un WorkRequest
.
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)
// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()
Políticas para actualizar el trabajo
Anteriormente, la solución recomendada para actualizar el trabajo periódico era poner en cola
PeriodicWorkRequest
por la política ExistingPeriodicWorkPolicy.REPLACE
Si había un PeriodicWorkRequest
pendiente con el mismo id
único, el nuevo
la solicitud de trabajo la cancelaría y la borraría. Esta política ahora está obsoleta en
favorecer el flujo de trabajo con ExistingPeriodicWorkPolicy.UPDATE
.
Por ejemplo, cuando usas enqueueUniquePeriodicWork
con una
PeriodicWorkRequest
, puedes inicializar el nuevo PeriodicWorkRequest
con el
ExistingPeriodicWorkPolicy.UPDATE
. Si hay una solicitud
PeriodicWorkRequest
con el mismo nombre único, WorkManager lo actualiza al
nueva especificación. Con este flujo de trabajo, no es necesario usar
updateWork()