WorkManager如何安排对REST API的GET请求?

Arn*_*bee 15 android android-workmanager

我已经看过WorkManager的codelab以及这里的一些例子,但是我看到的代码中的所有内容都与在设备上本地工作或上传到服务器有关,而不是下载数据和响应收到的数据.在开发人员指南中,它甚至说,"例如,一个应用程序可能需要不时地从网络上下载新资源",所以我认为这对于这项任务来说是完美的.我的问题是,如果WorkManager可以处理以下场景,如果没有,那么处理它的正确工具是什么:

  1. 安排一天在后台运行一次的工作
  2. 工作是从REST API进行数据提取(如果可能,将其发布到LiveData对象).
  3. 数据返回时,检查它是否比本地数据更新.
  4. 通知用户新数据可用.

我的worker类看起来像这样:

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)
}
Run Code Online (Sandbox Code Playgroud)

我的问题当然是LiveData对象无法观察,因为没有活动或片段可以作为其LifecycleOwner.但即使我使用来自API的回调来响应到达的数据,我的工作人员已经发布它是成功的,它可能不会继续回调,对吧?所以我知道这种方法是完全错误的,但是我看不到任何使用WorkManager获取数据的代码

请帮助一个正确的解决方案和一些示例代码或一些链接,如果它可以处理这种工作或其他更合适的话,可以使用WorkManager.

kph*_*hil 13

  1. 安排一天在后台运行一次的工作

您可以安排一个PeriodicWorkRequestfor,它应该排队等候enqueueUniquePeriodicWork.这样可以确保一次只能PeriodicWorkRequest激活一个特定名称.

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);
Run Code Online (Sandbox Code Playgroud)
  1. 工作是从REST API进行数据提取(如果可能,将其发布到LiveData对象).

这可以通过在doWork()您的工作人员内同步发送您的请求来完成.我不会LiveData在你的Worker课堂上使用.我们稍后再来.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;
}
Run Code Online (Sandbox Code Playgroud)
  1. 数据返回时,检查它是否比本地数据更新.

您以同步方式获取了API数据.同步获取本地数据并执行您需要做的任何事情来比较它们.

  1. 通知用户新数据可用.

如果您安排任务,WorkManager则保证运行,即使您的应用程序强制退出或设备重新启动.因此,当您的应用未运行时,您的任务可能会完成.如果您想在任何情况下通知用户,您可以发送通知.如果要在特定屏幕内通知用户,可以订阅任务状态.例如这样(取自官方指南):

WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(lifecycleOwner, workStatus -> {
    // Do something with the status
    if (workStatus != null && workStatus.getState().isFinished()) {
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

还有getStatusesForUniqueWork(String uniqueWorkName)我们的例子.

官方指南还解释了如何从您的数据返回任务,您可以setValue()在其上调用您MutableLiveData的例子.

我建议更新您的本地数据Worker,订阅您的工作人员状态,一旦成功更新您的UI与本地数据(如果您没有订阅您的本地数据,无论如何,与房间和LiveData).