Reputation: 1691
I have a bottom bar with four tabs. Each tab is a Fragment
. I want to stop any network calls when user moves to another Fragment
so I'm adding all Observable
calls to a CompositeSubscription
and I unsubscribe from them in onDestroyView()
. Next time user enters the screen all network calls fail (since I have unsubscribed) so I want to subscribe again.
I'm not sure how I am supposed to do this : somehow I have to re-subscribe when onResume()/onViewAttached()
is called for the Fragment. I'm using RxJava 1.
Edit : I have checked similar questions and their answers mention cache
and replay
operators but I don't think that's the case cause they were asking to also get the previously emitted items, while I just want to be able to perform again any network calls.
This is how I'm subscribing to an Observable for a network call :
subscriptions.add(remoteDataSource.getFeedMore(localDataSource.getFirstStoredId())
.doOnNext(new Action1<FeedItemsRequestDetailsWrapper>() {
@Override
public void call(FeedItemsRequestDetailsWrapper wrapper) {
if (wrapper != null) {
localDataSource.saveFeed(wrapper.getFeedItemList());
localDataSource.saveServerState(wrapper.getFeedRequestDetails());
}
}
})
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.mainThread())
.subscribe(new Action1<FeedItemsRequestDetailsWrapper>() {
@Override
public void call(FeedItemsRequestDetailsWrapper wrapper) {
// call to View to update
}
}));
And how I unsubscribe :
@Override
public void unsubscribe() {
if (subscriptions != null && subscriptions.hasSubscriptions()) {
subscriptions.unsubscribe();
}
}
Example Use Case : user enters Timeline
screen, user clicks a button and a network call is executed ( modeled as an Observable
in my Presenter class like the code I posted right above ). Then user exits this screen (
onDestroyView()
is called and any subscriptions are unsubscribed). Some time later user enters Timeline
screen again and clicks the button.
This is when I receive HTTP FAILED: java.io.IOException: Canceled
cause I have unsubscribed and I want to re-subscribe again so I can execute the network call without errors.
Thanks
Upvotes: 0
Views: 731
Reputation: 7045
Update
If you call unsubscribe in CompositeSubscrition
you can't add new subscriptions to it again. If you want to use the same composite instance again, then you need to call subscriptions.clear()
or you can create a new instance when the fragment is initialized.
Prev
First things first, if you unsubscribe from any observable/stream/flowable etc. you gonna lose the any incoming data/events.
If you want to get the latest result of an subscription then obviously you should do it before unsubscribe happens.
The problem here is your subscriptions should not be dependant on any Fragment
or Activity
lifecycle unless it's totally finished/destroyed.
So if you know that you have long requests you should subscribe them on a android.app.Service
.
Then you will face another problem communicating back and forth between Services
and Fragments/Activities
.
The easy solution on your case is you can create a BehaviourSubject
in a singleton class (better to use Dagger
to inject that model
to both fragment and service). Then in your Service
subscribe to your long running stream and publish the next events to that BehaviourSubject
BehaviourSubject
saves the last emitted data. So next time you subscribe them in your newly created fragment it will start with the last emitted item.
Of course this answer just cover one use-case according to your needs you may need to do something else.
Upvotes: 1