WorkManager consente di aggiornare una WorkRequest
quando è già stato creato
l'ha in coda. Questa operazione è spesso necessaria nelle app di grandi dimensioni che cambiano spesso
i vincoli o la necessità di aggiornare
i lavoratori in tempo reale. A partire da WorkManager
versione 2.8.0, l'API updateWork()
è il mezzo per eseguire questa operazione.
Il metodo updateWork()
ti consente di modificare alcuni aspetti di un
WorkRequest
al volo, senza dover effettuare manualmente
annullarne e accodarne una nuova. Questo semplifica notevolmente lo sviluppo
e il processo di sviluppo.
Evita di annullare il lavoro
In genere dovresti evitare di annullare una WorkRequest esistente e di accodare una nuova uno. Questa operazione può comportare la ripetizione di determinate attività nell'app e può richiedere la tua richiesta scrivere una notevole quantità di codice aggiuntivo.
Esamina i seguenti esempi di casi in cui l'annullamento di una WorkRequest può causare difficoltà:
- Richiesta backend: se annulli una
Worker
mentre è in fase di elaborazione. un payload da inviare al server, il nuovoWorker
deve ricominciare da capo e ricalcolare il payload potenzialmente costoso. - Programmazione: se annulli una
PeriodicWorkRequest
e vuoi come il nuovoPeriodicWorkRequest
da eseguire con la stessa programmazione, devi per calcolare un offset temporale e assicurare che il nuovo tempo di esecuzione sia allineato richiesta di lavoro precedente.
L'API updateWork()
consente di aggiornare i vincoli e le
altri parametri senza il problema di annullare e accodare una nuova richiesta.
Quando annullare il lavoro
In alcuni casi devi annullare direttamente un WorkRequest
anziché
chiama updateWork()
. Ecco cosa devi fare quando vuoi modificare
fondamentale dell'opera che hai accodato.
Quando aggiornare l'indirizzo di lavoro
Immagina un'app di foto che esegue un backup giornaliero delle foto dell'utente. Ha
ha accodato una PeriodicWorkRequest
per farlo. WorkRequest
ha vincoli
che richiedono che il dispositivo sia in carica e connesso al Wi-Fi.
Tuttavia, l'utente ricarica il dispositivo solo per 20 minuti al giorno utilizzando un
caricabatterie. In questo caso, l'app potrebbe voler aggiornare WorkRequest
per allentare il
di ricarica, in modo che il dispositivo possa caricare le foto anche se
non sia completamente carico.
In questo caso, puoi usare il metodo updateWork()
per aggiornare il lavoro
dai vincoli della richiesta.
Come aggiornare l'indirizzo di lavoro
Il metodo updateWork()
fornisce un semplice mezzo per aggiornare un modello esistente
WorkRequest
, senza dover annullare e accodarne uno nuovo.
Per utilizzare l'aggiornamento del lavoro in coda:
- Recupera l'ID esistente per il lavoro accodato: recupera l'ID della risorsa WorkRequest
vorresti aggiornare. Puoi recuperare questo ID con uno qualsiasi dei
API di
getWorkInfo
o impostando manualmente l'ID dalla versione iniziale WorkRequest per il recupero successivo con la proprietà pubblicaWorkRequest.id
prima di accodarla. - Create new WorkRequest (Crea nuova WorkRequest): crea una nuova risorsa
WorkRequest
e utilizzaWorkRequest.Builder.setID()
per impostare il suo ID in modo che corrisponda a quello dell'attualeWorkRequest
. - Imposta vincoli: utilizza
WorkRequest.Builder.setConstraints()
per trasmettere Nuovi vincoli in WorkManager. - Chiama updateWork: passa la nuova richiesta WorkRequest a
updateWork()
.
Aggiorna esempio di lavoro
Ecco un esempio di snippet di codice in Kotlin che dimostra come utilizzare il metodo
Metodo updateWork()
per modificare i vincoli della batteria di un WorkRequest
utilizzato
per caricare foto:
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)
}
Gestire il risultato
updateWork()
restituisce un ListenableFuture<UpdateResult>
. Il dato
UpdateResult
può avere uno dei vari valori che indicano se
WorkManager è riuscito ad applicare le modifiche. Indica anche quando è stato possibile
per applicare la modifica.
Per ulteriori informazioni, consulta le updateWork()
e UpdateResult
riferimento.
Monitora il lavoro con generazioni
Ogni volta che aggiorni un WorkRequest
, la sua generazione viene incrementata di uno. Questo
ti consente di monitorare esattamente quale WorkRequest
è attualmente in coda.
Le generazioni ti offrono un maggiore controllo quando osserva, traccia e verifichi il lavoro
richieste.
Per generare un WorkRequest
, segui questi passaggi:
- WorkInfo: chiama
WorkManager.getWorkInfoById()
per recuperare un'istanza diWorkInfo
corrispondente aWorkRequest
.- Puoi chiamare uno dei vari metodi che restituiscono un valore
WorkInfo
. Per ulteriori informazioni informazioni, consulta il riferimento di WorkManager.
- Puoi chiamare uno dei vari metodi che restituiscono un valore
- getGeneration: chiama
getGeneration()
sull'istanza diWorkInfo
, Il valoreInt
restituito corrisponde alla generazione delWorkRequest
.- Tieni presente che non esiste un campo o una proprietà di generazione, ma solo
WorkInfo.getGeneration()
.
- Tieni presente che non esiste un campo o una proprietà di generazione, ma solo
Esempio di generazione di tracce
Di seguito è riportato un esempio di implementazione del flusso di lavoro descritto in precedenza per
recuperando la generazione di 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()
Norme per l'aggiornamento del lavoro
In precedenza, la soluzione consigliata per l'aggiornamento del lavoro periodico era quella di accodare un
PeriodicWorkRequest
con il criterio ExistingPeriodicWorkPolicy.REPLACE
.
Se ci fosse un PeriodicWorkRequest
in attesa con lo stesso id
univoco, il nuovo
richiesta di lavoro viene annullata ed eliminata. Questo criterio è ora ritirato in
a favore del flusso di lavoro utilizzando ExistingPeriodicWorkPolicy.UPDATE
.
Ad esempio, se utilizzi enqueueUniquePeriodicWork
con un oggetto
PeriodicWorkRequest
, puoi inizializzare il nuovo PeriodicWorkRequest
con il
ExistingPeriodicWorkPolicy.UPDATE
. Se è presente una richiesta
PeriodicWorkRequest
con lo stesso nome univoco, WorkManager lo aggiorna con
nuova specifica. Seguendo questo flusso di lavoro, non è necessario utilizzare
updateWork()
.