Mettre à jour un travail déjà mis en file d'attente

WorkManager vous permet de mettre à jour un WorkRequest lorsque vous avez déjà mis en file d'attente. Cela est souvent nécessaire dans les applications volumineuses qui changent fréquemment ou besoin de mettre à jour leurs nœuds de calcul à la volée. À partir de WorkManager via la version 2.8.0, l'API updateWork().

La méthode updateWork() vous permet de modifier certains aspects d'une WorkRequest à la volée, sans avoir à suivre le processus de l'annulation et la mise en file d'attente d'un nouveau. Cela simplifie considérablement le développement processus.

Éviter d'annuler un travail

En règle générale, évitez d'annuler une WorkRequest existante et de mettre en file d'attente une nouvelle requête 1. Cela peut entraîner la répétition de certaines tâches dans l'application et vous obliger à d'écrire une quantité importante de code supplémentaire.

Voici quelques exemples illustrant les cas où l'annulation d'une WorkRequest peut entraîner difficultés suivantes:

  • Requête backend:si vous annulez une Worker pendant qu'il est en cours de calcul une charge utile à envoyer au serveur, le nouveau Worker doit recommencer et de recalculer la charge utile potentiellement coûteuse.
  • Planification:si vous annulez une PeriodicWorkRequest et que vous comme le nouveau PeriodicWorkRequest pour qu'il s'exécute selon le même calendrier, vous devez pour calculer un décalage temporel afin de s'assurer que le nouveau temps d'exécution est aligné avec la demande de travail précédente.

L'API updateWork() vous permet de mettre à jour les contraintes et les d'autres paramètres sans avoir à annuler et à mettre en file d'attente une nouvelle requête.

Quand annuler une tâche ?

Dans certains cas, vous devez annuler directement un WorkRequest plutôt que appelez updateWork(). C'est la procédure à suivre lorsque vous souhaitez modifier fondamentale du travail que vous avez mis en file d'attente.

Quand mettre à jour le profil professionnel

Imaginez une application photo qui effectue une sauvegarde quotidienne des photos de l'utilisateur. Il contient a mis un PeriodicWorkRequest en file d'attente. WorkRequest présente des contraintes qui nécessitent que l'appareil soit en charge et connecté au Wi-Fi.

Cependant, l'utilisateur ne recharge son appareil que 20 minutes par jour à l'aide d'un le chargeur. Dans ce cas, l'application peut mettre à jour WorkRequest pour assouplir le pour pouvoir importer les photos même si l'appareil n'est pas complètement chargé.

Dans ce cas, vous pouvez utiliser la méthode updateWork() pour mettre à jour la tâche les contraintes de la requête.

Mettre à jour votre profil professionnel

La méthode updateWork() permet de mettre à jour facilement un élément WorkRequest, sans avoir à annuler et à mettre en file d'attente une nouvelle requête.

Pour utiliser la mise à jour d'une tâche en file d'attente, procédez comme suit:

  1. Obtenir l'ID existant pour le travail mis en file d'attente: obtenez l'ID de la requête de travail que vous souhaitez mettre à jour. Vous pouvez récupérer cet ID à l'aide de n'importe quelle getWorkInfo, ou en conservant manuellement l'ID depuis le WorkRequest pour une récupération ultérieure avec la propriété publique WorkRequest.id, avant de la mettre en file d'attente.
  2. Create new WorkRequest (Créer une WorkRequest) : créez un objet WorkRequest et utilisez WorkRequest.Builder.setID() pour définir son ID de sorte qu'il corresponde à celui WorkRequest
  3. Définir des contraintes: utilisez WorkRequest.Builder.setConstraints() pour transmettre la valeur Nouvelles contraintes WorkManager
  4. Call updateWork: transmettez la nouvelle WorkRequest à updateWork().

Mettre à jour l'exemple professionnel

Voici un exemple d'extrait de code en Kotlin qui montre comment utiliser le Méthode updateWork() pour modifier les contraintes de batterie d'un WorkRequest utilisé pour importer des photos:

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)
}

Gérer le résultat

updateWork() renvoie un ListenableFuture<UpdateResult>. La valeur UpdateResult peut avoir l'une des nombreuses valeurs qui indiquent si oui ou non WorkManager a pu appliquer vos modifications. Il indique également quand il a pu pour appliquer la modification.

Pour en savoir plus, consultez les updateWork() et les UpdateResult. référence.

Suivre le travail des générations

Chaque fois que vous mettez à jour un WorkRequest, sa génération s'incrémente d'une unité. Ce vous permet de savoir exactement quel élément WorkRequest est actuellement mis en file d'attente. Les générations vous offrent plus de contrôle pour observer, tracer et tester le travail requêtes.

Pour générer un WorkRequest, procédez comme suit:

  1. WorkInfo: appelez WorkManager.getWorkInfoById() pour récupérer une instance de WorkInfo correspondant à votre WorkRequest.
  2. getGeneration: appelez getGeneration() sur l'instance de WorkInfo Le Int renvoyé correspond à la génération du WorkRequest
    • Notez qu'il n'existe pas de propriété ni de champ de génération, mais uniquement le champ WorkInfo.getGeneration().

Exemple de génération de canal

Voici un exemple d'implémentation du workflow décrit ci-dessus pour récupération de la génération d'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()

Règles de mise à jour des tâches

Auparavant, la solution recommandée pour mettre à jour le travail périodique consistait à mettre en file d'attente PeriodicWorkRequest par la règle ExistingPeriodicWorkPolicy.REPLACE. S'il y avait un PeriodicWorkRequest en attente avec le même id unique, le nouveau demande de travail l’annulerait et la supprimerait. Cette règle est désormais obsolète dans le workflow à l'aide de ExistingPeriodicWorkPolicy.UPDATE.

Par exemple, lorsque vous utilisez enqueueUniquePeriodicWork avec un PeriodicWorkRequest, vous pouvez initialiser le nouveau PeriodicWorkRequest avec la Règle ExistingPeriodicWorkPolicy.UPDATE. S'il existe une PeriodicWorkRequest portant le même nom unique, WorkManager le met à jour vers la nouvelle spécification. Ainsi, il n'est pas nécessaire d'utiliser updateWork()