8

我想用新的 JetPack WorkManager(链接到codelabs)组件(在应用程序的沙箱分支中)替换我现有数据同步系统的作业调度方面。我现有的系统运行良好,但其中的一些新功能WorkManager会派上用场(例如链接)。

我当前的系统使用 sharedLiveData将正在进行的作业的进度传达给RecyclerView观察它的任何 UI 元素(在我的情况下)(我实际上是 SwitchMappingViewModel到 s 列表中SyncItem

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组件有多种方法(getStatusByIdgetStatusesByTag等)可用于检索带有一个或多个WorkStatuses 的 LiveData,但这些仅报告课程粒度状态(运行、成功、失败、已取消)。

向 UI 传达进度(例如“已下载 546/1234 个项目”)的推荐方式是什么?setOutputData/getOutputData对似乎更多地用于 s 之间的通信(Worker链接时我需要)而不是 UI。

附件是用户打开同步状态页面(已完成 2 个项目,正在进行中)时的屏幕截图(在我的应用程序的 [测试] 版本中使用我的旧方法)。

正在同步的屏幕截图

在最终产品中,用户将能够取消任何正在进行的工作并重新发出一次性工作请求。通常这些工作会被解雇PeriodicWorkRequest

4

2 回答 2

9

本机支持

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

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

观察 Worker 的进度:

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 现在支持 setProgressAsync() API,它允许它持久化中间进度。这些 API 允许开发人员设置 UI 可以观察到的中间进度。进度由 Data 类型表示,它是一个可序列化的属性容器(类似于输入和输出,并受到相同的限制)。

请参阅 Android 文档

于 2019-09-24T13:08:23.097 回答
8

最好的方法是将中间进度写入您自己的数据存储并公开LiveData<>. 我们正在考虑在未来的 Alpha 版中添加此功能。

于 2018-05-26T21:51:55.343 回答