Obserwuj postęp pośredniej instancji roboczej

WorkManager ma wbudowaną obsługę ustawiania i obserwowania postępu pośredniego w przypadku procesów roboczych. Jeśli proces roboczy działał, gdy aplikacja była na pierwszym planie, te informacje mogą być też wyświetlane użytkownikowi za pomocą interfejsów API, które zwracają LiveData obiektu WorkInfo.

ListenableWorker obsługuje teraz interfejs API setProgressAsync(), który umożliwia utrwalanie postępu pośredniego. Te interfejsy API pozwalają programistom ustawiać postęp pośredni, który może być obserwowany przez interfejs użytkownika. Postęp jest reprezentowany przez typ Data, który jest serializowalnym kontenerem właściwości (podobnym do input i output, oraz podlegającym tym samym ograniczeniom).

Informacje o postępie można obserwować i aktualizować tylko wtedy, gdy działa ListenableWorker. Próby ustawienia postępu w ListenableWorker po zakończeniu jego działania są ignorowane.

Informacje o postępie możesz też obserwować za pomocą jednej z metod getWorkInfoBy…() lub getWorkInfoBy…LiveData(). Te metody zwracają instancje WorkInfo, która ma nową getProgress() metodę zwracającą Data.

Aktualizowanie postępu

W przypadku programistów Java, którzy używają ListenableWorker lub Worker, interfejs API setProgressAsync() zwraca ListenableFuture<Void>. Aktualizowanie postępu jest asynchroniczne, ponieważ proces aktualizacji obejmuje przechowywanie informacji o postępie w bazie danych. W Kotlinie możesz użyć CoroutineWorker obiektu's setProgress() funkcji rozszerzenia, aby zaktualizować informacje o postępie.

Ten przykład pokazuje ProgressWorker. Gdy Worker się uruchamia, ustawia postęp na 0, a po zakończeniu aktualizuje wartość postępu do 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();
    }
}

Obserwowanie postępu

Aby obserwować informacje o postępie, użyj metod getWorkInfoById i uzyskaj odniesienie do WorkInfo.

Oto przykład, który używa getWorkInfoByIdFlow w Kotlinie i getWorkInfoByIdLiveData w Javie.

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

Obserwowanie stanu przyczyny zatrzymania

Aby sprawdzić, dlaczego Worker został zatrzymany, możesz zarejestrować przyczynę zatrzymania, wywołując WorkInfo.getStopReason():

Kotlin

workManager.getWorkInfoByIdFlow(syncWorker.id)
  .collect { workInfo ->
      if (workInfo != null) {
        val stopReason = workInfo.stopReason
        logStopReason(syncWorker.id, stopReason)
      }
  }

Java

  workManager.getWorkInfoByIdLiveData(syncWorker.id)
    .observe(getViewLifecycleOwner(), workInfo -> {
        if (workInfo != null) {
          int stopReason = workInfo.getStopReason();
          logStopReason(syncWorker.id, workInfo.getStopReason());
        }
  });

Więcej informacji o cyklu życia i stanach obiektów Worker znajdziesz w artykule Stany procesu roboczego.