オブザーバブルの購読を解除する方法について質問があります。私は2つのコードを持っていますが、どちらが良いかについては本当にわかりません。
例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();
}
私のオブザーバブルは1回しか放出されず、アクティビティはObservableからの呼び出しを待つべきではないことに言及する必要があります。
どっちがいいですか?
前もって感謝します
2つのオプションから、2番目のオプションの方が優れています。
最初の例では、onComplete()
メソッドのunsubscribing
は不要です。サブスクリプションのonComplete()
に到達した場合、サブスクリプションのサブスクリプションを解除する責任はもうありません。
2番目の例は正しい例です。 CompositeSubscription
の背後にある考え方は、複数のSubscriptions
を追加して、一度に(unsubscribe
)をクリーンアップできるということです。言い換えれば、これにより、購読を解除する必要があるSubscriptions
のリストを保持する必要がなくなります。
CompositeSubscription
を使用するトリッキーな部分は、一度unsubscribe
itすると、[〜#〜] not [〜#〜]再度使用します。理由の詳細については、 compositeSubscription.add() メソッドのドキュメントを確認できます。つまり、追加しようとしているサブスクリプションのサブスクリプションを直接解除します。これは意図的な決定でした(詳細については、こちらをご覧ください [〜#〜] here [〜#〜] )。
あなたの例に戻って、アクティビティのunsubscribe()
でonDestroy()
を呼び出すことは問題なく、メモリリークからあなたを救います。あなたのコメントに関して、test()
メソッドを複数回呼び出すと問題が発生する-あなたの問題はどこか別の場所にあると思います。あなたのユースケースはそれを複数回呼び出すことを許可すべきではないかもしれません、おそらく新しく受け取ったデータを使用する前に古いデータをクリーンアップする必要があるかもしれません。おそらくあなたが直面しているどんな種類の問題を詳細に説明したなら、私たちはもっと役立つでしょう。ただし、CompositeSubscription
に関する限り-あなたはそれを使用し、正しくサブスクライブを解除しています!
onCompleted
でサブスクライブを解除する必要はありません。 観察可能な契約 を見てください
ObservableがそのオブザーバーにOnErrorまたはOnComplete通知を発行すると、サブスクリプションが終了します。オブザーバーは、この方法でObservableによって終了されたサブスクリプションを終了するために、サブスクライブ解除通知を発行する必要はありません。
一方、メモリリークを防ぐためには、onDestroy
でサブスクライブを解除する必要があります。
それはあなたのニーズ次第だと思います。アクティビティが他の呼び出しを待機しない場合、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();
}