Osserva i progressi intermedi dei lavoratori

WorkManager offre il supporto integrato per l'impostazione e l'osservazione dell'avanzamento intermedio dei worker. Se il worker era in esecuzione mentre l'app era in primo piano, queste informazioni possono essere mostrate all'utente anche utilizzando API che restituiscono il LiveData di WorkInfo.

ListenableWorker ora supporta l'API setProgressAsync(), che consente di mantenere lo stato intermedio. Queste API consentono agli sviluppatori di impostare un avanzamento intermedio che può essere osservato dalla UI. L'avanzamento è rappresentato dal tipo Data, che è un contenitore serializzabile di proprietà (simile a input e output e soggetto alle stesse limitazioni).

Le informazioni sull'avanzamento possono essere osservate e aggiornate solo durante l'esecuzione di ListenableWorker. I tentativi di impostare l'avanzamento di un ListenableWorker dopo il completamento dell'esecuzione vengono ignorati.

Puoi anche osservare le informazioni sullo stato di avanzamento utilizzando uno dei metodi getWorkInfoBy…() o getWorkInfoBy…LiveData(). Questi metodi restituiscono istanze di WorkInfo, che ha un nuovo metodo getProgress() che restituisce Data.

Aggiornamento avanzamento

Per gli sviluppatori Java che utilizzano ListenableWorker o Worker, l'API setProgressAsync() restituisce un ListenableFuture<Void>; l'aggiornamento dei progressi è asincrono, dato che la procedura di aggiornamento prevede l'archiviazione delle informazioni sui progressi 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. Worker imposta l'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();
    }
}

Osservare i progressi

Per osservare le informazioni sull'avanzamento, utilizza i metodi getWorkInfoById e ottieni un riferimento a WorkInfo.

Ecco un esempio che utilizza getWorkInfoByIdFlow per Kotlin e getWorkInfoByIdLiveData per 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
             }
      }
});

Per ulteriori informazioni sulla visualizzazione degli oggetti Worker, leggi Stati del lavoro e osservazione del lavoro. Per scoprire come ottenere stopReason quando il lavoro termina in modo imprevisto, consulta Osserva lo stato del motivo dell'interruzione.