Observer la progression des workers intermédiaires

WorkManager offre une prise en charge de premier ordre pour la définition et l'observation des progrès intermédiaires pour les nœuds de calcul. Si le nœud de calcul était en cours d'exécution alors que l'application était au premier plan, ces informations peuvent également être présentées à l'utilisateur à l'aide d'API qui renvoient le 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 simple. 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

L'observation des informations sur la progression est également très simple. Vous pouvez utiliser les méthodes getWorkInfoBy…() ou getWorkInfoBy…LiveData() et obtenir une référence à WorkInfo.

Voici un exemple qui utilise l'API getWorkInfoByIdLiveData.

Kotlin

WorkManager.getInstance(applicationContext)
    // requestId is the WorkRequest id
    .getWorkInfoByIdLiveData(requestId)
    .observe(observer, Observer { 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.