Наблюдайте за промежуточным прогрессом работника

WorkManager имеет встроенную поддержку настройки и отслеживания промежуточного прогресса для воркеров. Если воркер выполнялся, пока приложение находилось в активном режиме, эту информацию также можно показать пользователю с помощью API, возвращающих LiveData из WorkInfo .

ListenableWorker теперь поддерживает API setProgressAsync() , позволяющий сохранять промежуточные данные о ходе выполнения. Эти API позволяют разработчикам устанавливать промежуточные данные о ходе выполнения, которые можно отслеживать в пользовательском интерфейсе. Прогресс представлен типом Data , представляющим собой сериализуемый контейнер свойств (аналогично input и output и подчиняющийся тем же ограничениям).

Информацию о ходе выполнения можно отслеживать и обновлять только во время работы ListenableWorker . Попытки установить ход выполнения для ListenableWorker после завершения его выполнения игнорируются.

Вы также можете отслеживать ход выполнения, используя методы getWorkInfoBy…() или getWorkInfoBy…LiveData() . Эти методы возвращают экземпляры WorkInfo , в котором появился новый метод getProgress() , возвращающий Data .

Прогресс обновления

Для разработчиков Java, использующих ListenableWorker или Worker , API setProgressAsync() возвращает ListenableFuture<Void> ; обновление информации о ходе выполнения происходит асинхронно, поскольку процесс обновления включает сохранение информации о ходе выполнения в базе данных. В Kotlin для обновления информации о ходе выполнения можно использовать функцию расширения setProgress() объекта CoroutineWorker .

В этом примере показан ProgressWorker . При запуске Worker устанавливает свой прогресс на 0, а после завершения обновляет значение прогресса до 100.

Котлин

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

Ява

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

Наблюдение за прогрессом

Чтобы просмотреть информацию о ходе выполнения, используйте методы getWorkInfoById и получите ссылку на WorkInfo .

Вот пример, который использует getWorkInfoByIdFlow для Kotlin и getWorkInfoByIdLiveData для Java.

Котлин

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

Ява

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

Дополнительную информацию о наблюдении за объектами Worker см. в разделах «Состояния процесса» и «Наблюдение за процессом» . Чтобы узнать, как получить stopReason при неожиданном завершении процесса, см. раздел «Наблюдение за состоянием причины остановки» .