Search code examples
androidrx-java2android-architecture-componentsandroid-jetpackandroid-workmanager

Synchronous or Asynchronous Rxjava inside the Worker (from WorkManager component) what's the right choice?


I'm new to the new architecture component WorkManager, I do my API calls via Retrofit and RxJava.

My use case here is to get new posts from the Backend, then show notification, and update a widget.

So the code inside doWork() method from the Worker class, may look like something like this.

@NonNull
  @Override
  public Result doWork() {
    AppDependencies appDependencies = new AppDependencies((Application) getApplicationContext());
    Repository repository = appDependencies.getRepository();

    repository.getNewPosts()
        .flatMap(newPosts -> repository.inserPosts(newPosts).toObservable())
        .doOnError(Timber::e)
        //if success - > return  Result.SUCCESS,
        // -> show notification
        // -> update widget
        // error-> return Result.Failure
        .dontKnowWhatBestNextThing; //blocking or subscribing

    //if we reached here then Retry
    return Result.RETRY;
  }

My Question is what is the right way to use a RxJava code inside the Worker Class because the doWork() method has a return value, so Do I have to make Rx code Synchronous.

if I'm using the nonblocking Rx approach, how can I return value (Success - Failure - Retry)


Solution

  • Since WorkManager version 1.0.0-alpha12 they added a new artifact called work-rxjava2 that includes RxWorker class exactly for this purpose. It is a special case of ListenableWorker expecting Single<Result>.

    To implement it, first make sure you include correct artifacts to your build.gradle:

    dependencies {
       ...
       implementation "android.arch.work:work-runtime-ktx:$work_version"
       implementation "android.arch.work:work-rxjava2:$work_version"
    }
    

    And implement your RxWorker:

    class MyRxWorker(context : Context, params : WorkerParameters) : RxWorker(context, params) {
    
        val remoteService = RemoteService()
    
        override fun createWork(): Single<Result> {
            return remoteService.getMySingleResponse()
                    .doOnSuccess { /* process result somehow */ }
                    .map { Result.success() }
                    .onErrorReturn { Result.failure() }
        }
    }