Good morning, I am recently taken up playing around with RxJava and I am facing a problem.
I have a Fragment in a ViewPager which on onViewCreated() launches an HTTP request (handled by Retrofit and RxJava) to retrieve a list of Strings. The way it does it is by creating a subscription and adding it to a CompositeSubscription object
here is the code
final Subscription subscription = MyManager.getService().getListStringsFromWeb()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<String>() {
@Override
public void onCompleted() {
// DO NOTHING
}
@Override
public void onError(Throwable e) {
// DO SOMETHING
}
@Override
public void onNext(List<String> result) {
returnResultToView(result);
}
});
addSubscription(subscription);
In the Fragment on onViewCreated() I check for the result being there, if there is not we call the method above, if there is we are happy as a clam.
The problem is that when I rotate the device the "first" subscription has yet to return, therefore the data is not remembered by the fragment and it launches another search, and if I keep rotating I keep adding subscriptions
I would like to know if there is a way to hold on the first subscription and when its result arrives just give it back to the Fragment and disregarding all the other subscriptions
STEP BY STEP DESIRED BEHAVIOR:
- Launch Fragment and request
- Screen shows loading image and background the subscription/request is launched
- Multiple screen rotation holding the loading image since the first request is still pending
- Once the result of the first call comes back return it to the fragment, and hence hide loading image and show result
Thank you very much
The unfortunate thing regarding Fragments and RxJava is that you have to keep the observable around somehow. One method is to make them static to the
Fragment
so that you only create them once, then subscribe/unsubscribe inonStart()
/onStop()
or however you decide.The alternate approach if you don't like making static variables is to use a retained Fragment which handles the data. The View
Fragment
which shoes the data can then "bind" itself to the data Fragment. The advantages of this method is that the data is easily available to all components of an Activity, it abstracts away the data from the view for easy testing, and it outlives lifecycle components.So for a retained fragment you'd do something like this:
Add the
DataFragment
to the FragmentManager like so:Then on the ViewFragment you can subscribe to it similarly like this:
Now, your ViewFragment can disappear and re-appear on a whim without obstructing the download. It's easier to manipulate the Observables in ways that you need as well.