Когда отменить подписку на подписку

У меня вопрос о том, как отменить подписку на наблюдаемые. У меня есть два кода, и я не уверен, что лучше.

Пример 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(); } 

Я должен упомянуть, что мои наблюдаемые только выйдут один раз, активность не должна ждать больше звонков из Наблюдаемого.

Какая из них лучше?

заранее спасибо

Solutions Collecting From Web of "Когда отменить подписку на подписку"

Из двух вариантов второй лучше.

В первом примере вы отказываетесь от unsubscribing в методе onComplete() который не нужен. Если вы достигнете onComplete() подписки, вы больше не обязаны отписываться от нее.

Ваш второй пример правильный. Идея CompositeSubscription состоит в том, что вы можете добавить несколько Subscriptions на нее, а затем очистить ( unsubscribe ) сразу. Другими словами, это просто избавляет вас от необходимости хранить список Subscriptions которые вам нужно отменить.

Одна сложная часть, использующая CompositeSubscription заключается в том, что если вы однажды ее не unsubscribe , вы НЕ можете использовать ее снова. Почему вы можете проверить документацию для метода compositeSubscription.add () . Короче говоря, он будет напрямую отменить подписку, которую вы хотите добавить. Это было преднамеренное решение (вы можете больше узнать об этом ЗДЕСЬ ).

Вернемся к вашему примеру, вызвав onDestroy() unsubscribe() в onDestroy() для Activity, и это избавит вас от утечек памяти. Что касается вашего комментария о том, что проблемы возникают при вызове метода test() несколько раз – я бы сказал, что ваша проблема находится где-то в другом месте. Возможно, ваш случай использования не должен позволять называть его несколько раз, может быть, вы должны очистить старые данные, прежде чем использовать только что полученный, и т. Д. Возможно, если вы подробно объясните, с какими проблемами вы столкнетесь, мы можем помочь больше. Но что касается CompositeSubscription , вы используете его и отменяете от него правильно!

Нет необходимости отписаться в onCompleted . Взгляните на «Наблюдаемый контракт»

Когда Observable выдает уведомление OnError или OnComplete своим наблюдателям, это заканчивает подписку. Наблюдателям не нужно высылать уведомление об отказе подписки для завершения подписки, которая таким образом заканчивается Observable.

С другой стороны, вы обязательно должны отказаться от подписки в onDestroy , чтобы предотвратить утечку памяти.

Я думаю, это зависит от ваших потребностей. Если активность не будет ждать каких-либо других вызовов, я полагаю, вы могли бы отказаться от подписки внутри onCompleted ().

Я всегда отписываюсь в onDestroy ()

 @Override protected void onDestroy() { super.onDestroy(); if (subscription != null) { subscription.unsubscribe(); } } 

EDIT: взгляните на 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(); }