How does WorkManager schedule GET requests to REST API?

前端 未结 2 1612
梦如初夏
梦如初夏 2021-02-07 08:22

I\'ve had a look at the codelab for WorkManager plus some examples on here, but everything in code I have seen is either related to doing work locally on the device or work uplo

2条回答
  •  失恋的感觉
    2021-02-07 08:47

    1. Schedule a job that runs once a day in background

    You can schedule a PeriodicWorkRequest for that, which should be queued with enqueueUniquePeriodicWork. This makes sure only one PeriodicWorkRequest of a particular name can be active at a time.

    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);
    
    1. The job is to do a data fetch from the REST API (and post it to a LiveData object if possible).

    This can by done by sending your request synchronously within doWork() of your worker. I wouldn't use LiveData within your Worker class. We come to that later. The API call would look with Retrofit for example like that:

    @Override
    public WorkerResult doWork() {
         Call call = APILayer.getInstance().fetchData();
         Response response = call.execute();
         if (response.code() == 200) {
              MyData data = response.body();
              // ...
         } else {
              return Result.RETRY;
         }
         // ...
         return Result.SUCCESS;
    }
    
    1. When the data returns, check that it is newer than local data.

    You fetched your API data in a synchronous way. Fetch your local data also synchronously and do whatever you need to do to compare them.

    1. Notify the user that new data is available.

    If you schedule a task with WorkManager it is guaranteed to run, even if your app is force-quit or the device is rebooted. So your task might complete while your app is not running. If you want to notify the user in any case you can send a notification. If you want to notify the user within a certain screen you can subscribe on your tasks status. For example like this (taken from the official guide):

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

    There's also getStatusesForUniqueWork(String uniqueWorkName) for our example.

    The official guide is also explaining how to return data from you Task with which you can call setValue() on your MutableLiveData for example.

    I would propose to update your local data within your Worker, subscribe on your workers status and once it succeeds update your UI with the local data (if you are not subscribed on your local data anyways, i.e. with Room and LiveData).

    Edit: In reference to point 4, reading status of periodic work requests works a little different. They are only switching between ENQUEUED and RUNNING until CANCELLED. But will never have the state SUCCEEDED or FAILED. So listening for isFinished() might not be what you are expecting.

提交回复
热议问题