我有一个关于如何取消订阅可观察量的问题。我有两个代码,我不确定哪一个更好。
实施例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 - &gt;一旦活动被销毁,取消订阅订阅:
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只会发出一次,活动不应该等待来自Observable的更多调用。
哪一个更好?
提前致谢
答案 0 :(得分:28)
无需在onCompleted
取消订阅。看看The Observable Contract
当Observable向其发出OnError或OnComplete通知时 观察者,这结束了订阅。观察员不需要发布 取消订阅通知以结束订阅 以这种方式观察。
另一方面,您绝对应该取消订阅onDestroy
以防止内存泄漏。
答案 1 :(得分:28)
从两个选项中,第二个选项更好。
在您的第一个示例中,您在unsubscribing
方法中onComplete()
不需要。如果您到达订阅的onComplete()
,您就不再有责任取消订阅。
你的第二个例子是正确的。 CompositeSubscription
背后的想法是,您可以向其添加多个Subscriptions
,然后立即清理(unsubscribe
)。换句话说,这只是让您无需保留需要取消订阅的Subscriptions
列表。
使用CompositeSubscription
的一个棘手的部分是,如果你曾经unsubscribe
它,你可以不再次使用它。您可以查看compositeSubscription.add()方法的文档以获取详细信息。简而言之 - 它将直接取消订阅您尝试添加的订阅。这是一个刻意的决定(你可以阅读更多关于它的HERE)。
回到您的示例,在Activity的unsubscribe()
中调用onDestroy()
很好,可以避免内存泄漏。关于您多次拨打test()
方法时出现问题的评论 - 我说您的问题出在其他地方。也许你的用例不应该允许多次调用它,也许你应该在使用新收到的数据之前清理旧数据,等等。也许你已经详细解释了你面临的问题,我们可以提供更多帮助。但就CompositeSubscription
而言 - 您正在使用它并正确取消订阅!
答案 2 :(得分:5)
我认为这取决于您的需求。如果活动不会等待任何其他调用,我想你可以取消订阅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();
}