Search code examples
android-workmanagerretry-logic

How to create a PeriodicWorkRequest with retry logic in java for Android WorkManager?


Any way to pass workInfo.getRunAttemptCount() from my MainActivity to the Class extending Worker? So I can track the retry count and repeat for 3 iterations and call a RESULT.failure() state inside doWork() after 3 retries if the request was not successful.

Code :

    public Result doWork() {

        Integer retryAttemptCount = getInputData().getInt("retryAttempts",0);

        Log.e(TAG, "doWork: Work is done." + System.currentTimeMillis());


        if (retryAttemptCount > 3)
            return Result.failure();
        else
            return Result.retry();
    }

MainActivity

 private void setPeriodicWorkRequest(){

        Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();

        // Exponential retry with a min of 15 minutes during retry.
        PeriodicWorkRequest periodicWork = new
                PeriodicWorkRequest.Builder(MyPeriodicWork.class, 15, TimeUnit.MINUTES)
                .addTag("periodic_work")
                .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
                .setConstraints(constraints)
                .build();
        WorkManager.getInstance(getApplicationContext()).enqueueUniquePeriodicWork("periodic_work", ExistingPeriodicWorkPolicy.KEEP, periodicWork);

        WorkManager.getInstance(getApplicationContext()).getWorkInfoByIdLiveData(periodicWork.getId())
                .observe(this, new Observer<WorkInfo>() {
                    @Override
                    public void onChanged(@Nullable WorkInfo workInfo) {
                        Data.Builder data = new Data.Builder();

                        if (workInfo != null && workInfo.getRunAttemptCount() > 0) {
                            // Passing params
                            data.putInt("retryAttempts", workInfo.getRunAttemptCount());

                        }else{
                            data.putInt("retryAttempts", 0);
                        }
                    }
                });
}

Solution

  • You can call getRunAttemptCount() directly in your Worker class; it is one ListenableWorker's methods:

    public class UploadWorker extends Worker {
    
        public UploadWorker(
            @NonNull Context context,
            @NonNull WorkerParameters params) {
            super(context, params);
        }
    
        @Override
        public Result doWork() {
          // Do the work here--in this case, upload the images.
          Integer retryAttemptCount = getRunAttemptCount();
    
          try {
    
            uploadImages()
            return Result.success();
    
          } catch (Exception exception) {
            if (retryAttemptCount >= 3)
                return Result.failure();
            else
                return Result.retry();
            }
        }
    }