Osserva i progressi intermedi dei lavoratori

WorkManager offre un supporto di primo livello per l'impostazione e l'osservazione dei progressi intermedi per i worker. Se il worker era in esecuzione mentre l'app si trovava in primo piano, queste informazioni possono essere mostrate anche all'utente utilizzando le API che restituiscono il valore LiveData di WorkInfo.

ListenableWorker ora supporta l'API setProgressAsync(), che permette di mantenere i progressi intermedi. Queste API consentono agli sviluppatori di impostare progressi intermedi che possono essere osservati dall'interfaccia utente. L'avanzamento è rappresentato dal tipo Data, che è un contenitore serializzabile di proprietà (simile a input e output e soggetto alle stesse restrizioni).

Le informazioni sull'avanzamento possono essere osservate e aggiornate solo mentre ListenableWorker è in esecuzione. I tentativi di impostare l'avanzamento di una ListenableWorker al termine dell'esecuzione vengono ignorati. Puoi anche osservare le informazioni sui progressi utilizzando uno dei metodi getWorkInfoBy…() o getWorkInfoBy…LiveData(). Questi metodi restituiscono istanze di WorkInfo, che ha un nuovo metodo getProgress() che restituisce Data.

Aggiornamento dei progressi

Per gli sviluppatori Java che utilizzano un elemento ListenableWorker o Worker, l'API setProgressAsync() restituisce un ListenableFuture<Void>. L'aggiornamento dell'avanzamento è asincrono, dato che il processo di aggiornamento comporta l'archiviazione delle informazioni di avanzamento in un database. In Kotlin, puoi utilizzare la funzione di estensione setProgress() dell'oggetto CoroutineWorker per aggiornare le informazioni sullo stato di avanzamento.

Questo esempio mostra un ProgressWorker semplice. Worker imposta il proprio avanzamento su 0 all'avvio e, al termine, aggiorna il valore di avanzamento a 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();
    }
}

Osservazione dei progressi

Anche osservare le informazioni sui progressi è semplice. Puoi utilizzare i metodi getWorkInfoBy…() o getWorkInfoBy…LiveData() e ottenere un riferimento a WorkInfo.

Ecco un esempio che utilizza 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
             }
      }
});

Per ulteriore documentazione sull'osservazione degli oggetti Worker, leggi Stati di lavoro e osservazione del lavoro.