Observer la progression des workers intermédiaires

WorkManager est compatible avec la définition et l'observation de la progression intermédiaire des nœuds de calcul. Si le nœud de calcul était en cours d'exécution lorsque l'application était au premier plan, ces informations peuvent également être présentées à l'utilisateur via l'API qui renvoient les LiveData de WorkInfo.

ListenableWorker est désormais compatible avec l'API setProgressAsync(), ce qui lui permet de conserver une progression intermédiaire. Ces API permettent aux développeurs de définir une progression intermédiaire accessible par l'interface utilisateur. La progression est représentée par le type Data, qui est un conteneur de propriétés sérialisable (semblable à input et output, et soumis aux mêmes restrictions).

Les informations de progression ne sont accessibles et mises à jour que lorsque ListenableWorker est en cours d'exécution. Les tentatives de définition de la progression sur un ListenableWorker une fois que son exécution est terminée sont ignorées.

Les informations de progression sont accessibles via la méthode getWorkInfoBy…() ou getWorkInfoBy…LiveData(). Ces méthodes renvoient des instances de WorkInfo, qui possède une nouvelle méthode getProgress() qui renvoie Data.

Progression de la mise à jour

Pour les développeurs Java utilisant un ListenableWorker ou un Worker, l'API setProgressAsync() renvoie un ListenableFuture<Void> ; la progression de la mise à jour est asynchrone, car le processus de mise à jour implique le stockage des informations de progression dans une base de données. En langage Kotlin, vous pouvez utiliser la fonction d'extension setProgress() de l'objet CoroutineWorker pour mettre à jour les informations de progression.

Cet exemple présente un ProgressWorker. Le Worker définit sa progression sur 0 lorsqu'il commence et, une fois qu'il a terminé, il définit la valeur de progression sur 100.

Kotlin

import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.WorkerParameters
import kotlinx.coroutines.delay

class ProgressWorker(context: Context, parameters: WorkerParameters) :
    CoroutineWorker(context, parameters) {

    companion object {
        const val Progress = "Progress"
        private const val delayDuration = 1L
    }

    override suspend fun doWork(): Result {
        val firstUpdate = workDataOf(Progress to 0)
        val lastUpdate = workDataOf(Progress to 100)
        setProgress(firstUpdate)
        delay(delayDuration)
        setProgress(lastUpdate)
        return Result.success()
    }
}

Java

import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

public class ProgressWorker extends Worker {

    private static final String PROGRESS = "PROGRESS";
    private static final long DELAY = 1000L;

    public ProgressWorker(
        @NonNull Context context,
        @NonNull WorkerParameters parameters) {
        super(context, parameters);
        // Set initial progress to 0
        setProgressAsync(new Data.Builder().putInt(PROGRESS, 0).build());
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            // Doing work.
            Thread.sleep(DELAY);
        } catch (InterruptedException exception) {
            // ... handle exception
        }
        // Set progress to 100 after you are done doing your work.
        setProgressAsync(new Data.Builder().putInt(PROGRESS, 100).build());
        return Result.success();
    }
}

Observer la progression

Pour observer les informations de progression, utilisez les méthodes getWorkInfoById et obtenez une référence à WorkInfo.

Voici un exemple qui utilise getWorkInfoByIdFlow pour Kotlin et getWorkInfoByIdLiveData pour Java.

Kotlin

WorkManager.getInstance(applicationContext)
      // requestId is the WorkRequest id
      .getWorkInfoByIdFlow(requestId)
      .collect { workInfo: WorkInfo? ->
          if (workInfo != null) {
              val progress = workInfo.progress
              val value = progress.getInt("Progress", 0)
              // Do something with progress information
          }
      }

Java

WorkManager.getInstance(getApplicationContext())
     // requestId is the WorkRequest id
     .getWorkInfoByIdLiveData(requestId)
     .observe(lifecycleOwner, new Observer<WorkInfo>() {
             @Override
             public void onChanged(@Nullable WorkInfo workInfo) {
                 if (workInfo != null) {
                     Data progress = workInfo.getProgress();
                     int value = progress.getInt(PROGRESS, 0)
                     // Do something with progress
             }
      }
});

Pour en savoir plus sur l'observation d'objets Worker, consultez États et observation du calcul. Pour savoir comment obtenir le stopReason lorsqu'un travail se termine de manière inattendue, consultez Observer l'état de la raison de l'arrêt.