我已经查看了 WorkManager 的代码实验室以及此处的一些示例,但我所看到的代码中的所有内容要么与在设备上本地工作有关,要么与上传到服务器的工作有关,而不是下载数据和响应收到的数据。在开发人员指南中甚至说,“例如,应用程序可能需要不时从网络下载新资源”,所以我认为它非常适合这项任务。我的问题是 WorkManager 是否可以处理以下情况,如果不能,处理它的合适工具是什么:
- 安排一个每天在后台运行一次的作业
- 工作是从 REST API 获取数据(如果可能,将其发布到 LiveData 对象)。
- 当数据返回时,检查它是否比本地数据新。
- 通知用户新数据可用。
我的 worker 类(Class)看起来像这样:
public class MyWorker extends Worker {
@NonNull
@Override
public WorkerResult doWork() {
lookForNewData();
return WorkerResult.SUCCESS;
}
public void lookForNewData() {
MutableLiveData<MyObject> liveData = new MutableLiveData<>();
liveData.observe(lifeCycleOwner, results -> {
notifyOnNewData(results);
})
APILayer.getInstance().fetchData(searchParams, liveData)
}
我的问题当然是LiveData对象无法观察,因为没有可以作为其LifecycleOwner的 Activity 或 fragment 。但即使我使用 API 的回调来响应到达的数据,我的工作人员也应该已经发布它成功并且它可能不会继续回调,对吗?所以我知道这种方法是完全错误的,但我看不到任何使用 WorkManager 获取数据的代码
请提供适当的解决方案和一些示例代码或一些链接,如果 WorkManager 可以处理此类工作,或者其他更合适的东西,请提供帮助。
最佳答案
- Schedule a job that runs once a day in background
您可以为此安排一个PeriodicWorkRequest
,它应该使用enqueueUniquePeriodicWork
排队。这可确保同一时间只有一个特定名称的 PeriodicWorkRequest
处于 Activity 状态。
Constraints constraint = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(MyWorker.class, 1, TimeUnit.DAYS)
.setConstraints(constraint)
.build();
WorkManager workManager = WorkManager.getInstance();
workManager.enqueueUniquePeriodicWork("my_unique_worker", ExistingPeriodicWorkPolicy.KEEP, workRequest);
- The job is to do a data fetch from the REST API (and post it to a LiveData object if possible).
这可以通过在您的工作人员的 doWork()
中同步发送您的请求来完成。我不会在您的 Worker
类中使用 LiveData
。我们稍后再谈。 API 调用在 Retrofit 中看起来像这样:
@Override
public WorkerResult doWork() {
Call<MyData> call = APILayer.getInstance().fetchData();
Response<MyData> response = call.execute();
if (response.code() == 200) {
MyData data = response.body();
// ...
} else {
return Result.RETRY;
}
// ...
return Result.SUCCESS;
}
- When the data returns, check that it is newer than local data.
您以同步方式获取了 API 数据。同步获取您的本地数据,并做任何您需要做的事情来比较它们。
- Notify the user that new data is available.
如果您使用 WorkManager
安排任务,它一定会运行,即使您的应用程序被强制退出或设备重新启动也是如此。因此,您的任务可能会在您的应用未运行时完成。如果您想在任何情况下通知用户,您都可以发送通知。如果您想在某个屏幕内通知用户,您可以订阅您的任务状态。例如像这样(取自 official guide ):
WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(lifecycleOwner, workStatus -> {
// Do something with the status
if (workStatus != null && workStatus.getState().isFinished()) {
// ...
}
});
我们的示例还有 getStatusesForUniqueWork(String uniqueWorkName)
。
官方指南还解释了如何从您的任务返回数据,您可以使用它在您的 MutableLiveData
上调用 setValue()
。
我建议在您的Worker
中更新您的本地数据,订阅您的工作人员状态,一旦它成功使用本地数据更新您的 UI(如果您无论如何都没有订阅您的本地数据,即使用 Room 和 LiveData
)。
编辑:关于第 4 点,定期工作请求的读取状态有点不同。它们只会在 ENQUEUED
和 RUNNING
之间切换,直到 CANCELLED
。但永远不会有状态 SUCCEEDED
或 FAILED
。因此监听 isFinished()
可能不是您所期望的。
关于android - WorkManager 如何调度 GET 请求到 REST API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50761374/