何时取消订阅
我有一个关于如何取消订阅observable的问题。我有两个代码,我不确定哪一个更好。何时取消订阅
例1 - >退订用户一旦流已完成:
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
progressdialog.dissmiss();
unsubscribe();
}
@Override
public void onError(Throwable e) {
progressdialog.dissmiss();
}
@Override
public void onNext(String s) {
// do something with data
}
}
例2 - >取消一旦活动被破坏订阅:
private void test(){
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
progressdialog.dissmiss();
}
@Override
public void onError(Throwable e) {
progressdialog.dissmiss();
}
@Override
public void onNext(String s) {
// do something with data
}
};
subscription = BackendRequest.login(loginRequest)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
compositeSubscription.add(subscription);
}
@Override
protected void onDestroy() {
super.onDestroy();
this.subscription.unsubscribe();
}
我不得不提到我的可观察者只会发射一次,该活动不应该等待来自Observable的更多呼叫。
哪一个更好?
在此先感谢
从这两个选项中,第二个更好。
在您的第一个示例中,您在onComplete()
方法中不需要unsubscribing
。如果您到达订阅的onComplete()
,则您不再有退订的责任。
你的第二个例子是正确的。 CompositeSubscription
背后的想法是,您可以添加多个Subscriptions
,然后立即清理(unsubscribe
)。换句话说,这只需要保留需要退订的Subscriptions
列表即可。
使用CompositeSubscription
一个棘手的部分是,如果你曾经unsubscribe
它,你可以不是再次使用它。您可以查看compositeSubscription.add()方法的文档以获取详细信息。简而言之 - 它会直接取消订阅您要添加的订阅。这是一个慎重的决定(你可以阅读更多关于它HERE)。
回到你的例子,在onDestroy()
的Activity中调用unsubscribe()
就可以了,并且可以节省内存泄漏。关于您在多次拨打test()
方法时发生问题的评论 - 我会说您的问题在其他地方。也许你的用例不应该多次调用它,也许你应该在使用新接收的数据之前清理旧数据等等。也许如果你已经详细解释了你面临的问题,我们可以帮助更多。但就CompositeSubscription
而言 - 您正在使用它并正确取消订阅!
但'onDestroy'不保证被调用。这是否意味着如果因为某种原因未调用'onDestroy',将会出现内存泄漏,因为在这种情况下'unsubscribe'不会被调用? – Storix
既然你的'Observable'只发出一个项目,为什么不使用'Single'呢?它不是'onNext()',而是一次调用'SingleSubscriber'的'onSuccess()',然后完成(没有'onComplete()'调用)。 –
我认为这取决于您的需求。如果该活动不会等待任何其他呼叫,我想您可以在onCompleted()内取消订阅。
我总是在退订的onDestroy()
@Override
protected void onDestroy() {
super.onDestroy();
if (subscription != null) {
subscription.unsubscribe();
}
}
编辑:看看http://reactivex.io/RxJava/javadoc/rx/subscriptions/CompositeSubscription.html
private CompositeSubscription mCompositeSubscription = new CompositeSubscription();
private void doSomething() {
mCompositeSubscription.add(
AndroidObservable.bindActivity(this, Observable.just("Hello, World!"))
.subscribe(s -> System.out.println(s)));
}
@Override
protected void onDestroy() {
super.onDestroy();
mCompositeSubscription.unsubscribe();
}
没有必要在onCompleted
退订。看看The Observable Contract
当可观察到的问题进行的OnError或通知的onComplete其 观察员,这结束认购。观察者不需要以这种方式发出 退订通知以结束由 Observable结尾的订阅。
另一方面,您绝对应该退订onDestroy
以防止内存泄漏。
我有麻烦让我的代码(用拉来刷新)刷新第二次时使用拉刷新监听器。我已经验证我的拉动刷新工作正常,但第二套“observable.subscribeOn(Schedulers.newThread())。observeOn(AndroidSchedulers.mainThread())。subscribe(subscriber)”不工作,只有第一套。有任何想法吗? – lawonga