Отображение подробного прогресса в работе рабочих WorkManager

Я хочу заменить аспект планирования заданий моей существующей системы синхронизации данных новым компонентом JetPack WorkManager (ссылка на кодовые метки) (в ветке "песочница" приложения). Моя существующая система работает хорошо, но некоторые новые функции в WorkManager пригодится (например, цепочки).

Моя текущая система использует общий LiveData сообщить о ходе выполнения задания любому элементу пользовательского интерфейса (RecyclerView в моем случае) наблюдая за этим (я на самом деле SwitchMapping в ViewModel в список SyncItems)

data class SyncItem(
        val title: String,
        private var _progress: Int,
        var total: Int) : BaseObservable() {

    var progress: Int
        @Bindable get() = _progress
        set(value) {
            _progress = value
            notifyPropertyChanged(BR.progress)
        }
}

Новый WorkManager компонент имеет несколько методов (getStatusById, getStatusesByTagи т. д.), которые можно использовать для получения LiveData с одним или несколькими WorkStatusДа, но они сообщают только о статусе курса (работает, успешно, не удалось, отменено).

Каков рекомендуемый способ передачи прогресса (например, "скачано 546/1234 элементов") в пользовательский интерфейс? setOutputData/getOutputData пара, кажется, больше используется для общения между Workers (что мне нужно при сцеплении), чем с пользовательским интерфейсом.

Прикрепленный снимок экрана показывает, как это выглядит (в [тестовой] версии моего приложения, использующей мой старый метод), когда пользователь открывает страницу состояния синхронизации (2 элемента завершены, остальные выполняются).

снимок экрана в процессе синхронизации

В конечном продукте пользователь сможет отменить любые незавершенные работы и повторно выдать разовые рабочие запросы. Обычно рабочие места будут уволены PeriodicWorkRequest,

1 ответ

Решение

Лучший способ сделать это - записать промежуточный прогресс в ваше собственное хранилище данных и предоставить LiveData<>, Мы рассматриваем возможность добавления этой функции в будущую альфа-версию.

Встроенная поддержка

implementation 'androidx.work:work-runtime:2.3.4'

Сообщите о прогрессе по Worker:

public class FooWorker extends Worker {

    public FooWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            setProgressAsync(new Data.Builder().putInt("progress", 0).build());
            Thread.sleep(1000);
            setProgressAsync(new Data.Builder().putInt("progress", 50).build());
            Thread.sleep(1000);
            setProgressAsync(new Data.Builder().putInt("progress", 100).build());

            return Result.success();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return Result.failure();
        }
    }
}

Наблюдайте за прогрессом рабочего:

WorkManager.getInstance(context).getWorkInfosForUniqueWorkLiveData("test").observe(lifecycleOwner, new Observer<List<WorkInfo>>() {
        @Override
        public void onChanged(List<WorkInfo> workInfos) {
            if (workInfos.size() > 0) {
                WorkInfo info = workInfos.get(0);
                int progress = info.getProgress().getInt("progress", -1);
                //Do something with progress variable
            }

        }
    });

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

См. Документацию по Android

Другие вопросы по тегам