Aggiornare il lavoro già accodato

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 nuovo Worker deve ricominciare da capo e ricalcolare il payload potenzialmente costoso.
  • Programmazione: se annulli una PeriodicWorkRequest e vuoi come il nuovo PeriodicWorkRequest 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:

  1. 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à pubblica WorkRequest.id prima di accodarla.
  2. Create new WorkRequest (Crea nuova WorkRequest): crea una nuova risorsa WorkRequest e utilizza WorkRequest.Builder.setID() per impostare il suo ID in modo che corrisponda a quello dell'attuale WorkRequest.
  3. Imposta vincoli: utilizza WorkRequest.Builder.setConstraints() per trasmettere Nuovi vincoli in WorkManager.
  4. 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:

  1. WorkInfo: chiama WorkManager.getWorkInfoById() per recuperare un'istanza di WorkInfo corrispondente a WorkRequest.
    • Puoi chiamare uno dei vari metodi che restituiscono un valore WorkInfo. Per ulteriori informazioni informazioni, consulta il riferimento di WorkManager.
  2. getGeneration: chiama getGeneration() sull'istanza di WorkInfo, Il valore Int restituito corrisponde alla generazione del WorkRequest.
    • Tieni presente che non esiste un campo o una proprietà di generazione, ma solo WorkInfo.getGeneration().

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().