首页 文章

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

提问于
浏览
12

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

  • 安排一天在后台运行一次的作业

  • 工作是从REST API进行数据提取(如果可能,将其发布到LiveData对象) .

  • 数据返回时,检查它是否比本地数据更新 .

  • 通知用户新数据可用 .

我的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)
}

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

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

2 回答

  • 5

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

    您可以为其安排 PeriodicWorkRequest ,应该使用 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);
    

    工作是从REST API进行数据提取(如果可能,将其发布到LiveData对象) .

    这可以通过在您的工作人员的 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;
    }
    

    数据返回时,检查它是否比本地数据更新 .

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

    通知用户新数据可用 .

    如果使用 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 ) .

  • 0

    这是最初的想法 . 如果我错了,请有人纠正我 .

    我的工作人员已经发布它已成功并且可能不会继续进行回调,对吧?

    我们可以使用来自API响应的回调,构造worker的输出数据并使用 worker.setOutputData() 设置它然后从workManager中收听 LiveData<WorkStatus> . 从这个工作状态,我们可以使用 workStatus.getOutputdata() 获取outputData . 这些数据可以为我们提供我们想要的API响应 .

    我们可以将此响应传递给工作链中的下一个worker,以执行更新本地DB等任务 .

相关问题