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 , вы можете зарегистрировать причину остановки, вызвав WorkInfo.getStopReason() :
Котлин
workManager.getWorkInfoByIdFlow(syncWorker.id)
.collect { workInfo ->
if (workInfo != null) {
val stopReason = workInfo.stopReason
logStopReason(syncWorker.id, stopReason)
}
}
Ява
workManager.getWorkInfoByIdLiveData(syncWorker.id)
.observe(getViewLifecycleOwner(), workInfo -> {
if (workInfo != null) {
int stopReason = workInfo.getStopReason();
logStopReason(syncWorker.id, workInfo.getStopReason());
}
});
Дополнительную документацию по жизненному циклу и состояниям объектов Worker см. в разделе Состояния Work .