Подтвердить что ты не робот

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

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

Пример 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.

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

Я думаю, это зависит от ваших потребностей. Если активность не будет ждать каких-либо других вызовов, я полагаю, вы могли бы отказаться от подписки внутри 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();
}