Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava resubscribe to event after activity restore

I'm still figuring out RxJava and using it to do some networking stuff with Retrofit 2. Been trying it our for a a couple days and like that the code looks more readable now but have come across an issue that I cant seem to figure a way around.

I am trying to perform a login (which returns an API token) and then use this token to fetch some initial data all in the same chain so that the output of the chain is the token + data. To do this I call my API service with a

apiClient
    .login()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(token -> getData(token))
    .subscribe(new Subscrber<Bundle>() {...});

This seemed fine, but I also wanted to show a progress bar when starting and stopping the chain. So I added a .doOnSubscribe() and a .doOnUnsubscribe() to this as well. However I noticed that after orientation change the fragment that I was trying to hide the progress bar is always null.

So I searched and came across the RxLifecycle lib that seemed like it would help and I now .cache() and unsubscribe from the event chain. But I cant figure out how to subscribe to the same event again in onCreate() after this? I think I'm missing something pretty basic and would appreciate any help with this.

like image 716
source.rar Avatar asked Dec 12 '15 19:12

source.rar


1 Answers

You don't necessarily have to use any architecture pattern to accomplish that. Though any MVP/MVC are nice things for concerns separation, testing etc, making your Controller/Presenter/DAO an application-wide singleton, which keeps up memory through whole application's life is not exactly a good idea.

Here's a sample project using retained fragment instance and RxJava - https://github.com/krpiotrek/RetainFragmentSample

The main idea there is to use Fragment with setRetainInstance(true) called, which protects it from being destroyed on orientation change, and store your Observable in there. Here's how you handle that in Activity/Fragment onCreate

protected void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        // first run, create observable
        mInfoObservable = createInfoObservable();
        // set Observable in retained fragment
        RetainFragmentHelper.setObject(this, getSupportFragmentManager(), mInfoObservable);
    } else {
        // following runs, get observable from retained fragment
        mInfoObservable = RetainFragmentHelper.getObjectOrNull(this, getSupportFragmentManager());
    }

    // subscribe 
    mInfoObservable.subscribe(...);
}

Keep in mind that your Observable has to cache last value, one way is to use cache() operator.

like image 136
krp Avatar answered Sep 27 '22 21:09

krp