Obserwuj postęp pośredniej instancji roboczej

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

Interfejs ListenableWorker obsługuje teraz interfejs API setProgressAsync(), który umożliwia zachowywanie postępów pośrednich. Te interfejsy API umożliwiają deweloperom ustawianie pośredniego postępu, który może być obserwowany przez interfejs. Postęp jest reprezentowany przez typ Data, który jest kontenerem właściwości, który można serializować (podobnie jak inputoutput, i podlega tym samym ograniczeniom).

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

Postępy możesz też śledzić za pomocą jednej z metod getWorkInfoBy…() lub getWorkInfoBy…LiveData(). Te metody zwracają instancje WorkInfo, które mają nową metodę getProgress() zwracającą Data.

Postęp aktualizacji

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

Ten przykład pokazuje ProgressWorker. Worker ustawia swój postęp na 0 % po rozpoczęciu, 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ępów

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

Oto przykład użycia funkcji getWorkInfoByIdFlow w przypadku Kotlina i getWorkInfoByIdLiveData w przypadku Javy.

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ło zatrzymane, możesz zarejestrować przyczynę zatrzymania, wywołując funkcję 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 zadań.