我想用新的JetPack WorkManager(链接到codelabs)组件(在应用程序的沙箱分支中)替换现有数据同步系统的作业调度方面。我现有的系统运行良好,但WorkManager
中的一些新功能会派上用场(例如链接)。
我当前的系统使用共享LiveData
将进度从正在进行的作业传递到任何UI元素(在我的情况下为RecyclerView
)观察它(我实际上是在{{中的SwitchMapping) 1}}到ViewModel
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
,getStatusById
等),可用于检索包含一个或多个getStatusesByTag
es的LiveData,但这些仅报告课程粒度状态(运行,成功,失败,取消)。
推荐进度的方法是什么(例如'546/1234项下载')到用户界面? WorkStatus
/ setOutputData
对似乎更多地用于getOutputData
(链接时我需要)与UI之间的通信。
附件是当用户打开同步状态页面(完成了2个项目,正在进行中)时,它的外观截图(使用我的旧方法在我的应用程序的[测试版]中)。
在最终产品中,用户可以取消正在进行的任何作业,并重新发出一次性工作请求。通常情况下,作业将由Worker
启动。
答案 0 :(得分:7)
最好的方法是将中间进度写入您自己的数据存储并公开LiveData<>
。我们正在考虑在未来的alpha中添加此功能。
答案 1 :(得分:3)
进度报告现在本地可用。目前仅在 beta 版本中。
implementation 'androidx.work:work-runtime:2.3.0-beta01'
报告工作人员进度:
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();
}
}
}
观察工作者的进度:
public class FooActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foo);
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class)
.build();
WorkManager.getInstance(this).beginUniqueWork(
"test", ExistingWorkPolicy.REPLACE, request).enqueue();
WorkManager.getInstance(this).getWorkInfosForUniqueWorkLiveData("test").observe(this, 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
}
}
});
}
}
ListenableWorkers现在可以通过 setProgressAsync() API设置进度。还在CoroutineWorker中添加了相应的可挂起的setProgress API,并在RxWorker中添加了一个返回Single的setProgress。使用这些新的API,工作人员可以通过具有相应getProgress API的 WorkInfo传达进度信息。 (b / 79481554)