Отказ от подписки на RxJava2 / RxAndroid PublishSubject

Пытаюсь заменить EventBus на RxAndroid.

Я хочу, чтобы страничные фрагменты подписывались / отказывались от подписки на источник событий, эти фрагменты создаются и отбрасываются относительно быстро, в зависимости от того, как быстро пользователь переходит на новую страницу.

В EventBus я смог добавить декорированный метод обратного вызова (т.е. @Subscribe(threadMode = ThreadMode.MAIN)) и зарегистрировать / отменить регистрацию в методах onStart / onStop фрагмента.

С помощью RxJava2 я теперь создаю объект PublishSubject в классе

public static PublishSubject<List<Long>> m_psUpdatedDays = PublishSubject.create();
public static void publishUpdatedDays(List<Long> lDay) {
    m_psUpdatedDays.onNext(lDay);
}

и подпишитесь на этого издателя в другом классе, вызвав следующее в методе onStart фрагмента:

m_psUpdatedDays.observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<Long>>() {
    @Override public void onSubscribe(Disposable d) {}
    @Override public void onNext(List<Long> longs) {
      ...
      Update Fragment UI here
      ...
    }
    @Override public void onError(Throwable e) {}
    @Override public void onComplete() {}
});

У меня вопрос: как я могу отказаться от подписки на этого нового наблюдателя, когда система вызывает метод onStop фрагмента?

Нужно ли мне сохранять объект Disposable, который я получаю в onSubscribe, а затем вызывать .dispose() для него в методе onStop?


person Daniel F    schedule 13.06.2018    source источник
comment
Теперь этот вопрос решен за меня. Помимо ответа Сарат Кн, это может быть полезным видео caster.io/lessons/rxjava-2 -compositedisposable   -  person Daniel F    schedule 14.06.2018


Ответы (1)


Вы можете использовать объект CompositeDisposable, который может хранить список расходных материалов, и все они могут быть удалены вместе.

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

    public abstract class BaseFragment extends Fragment {
        protected CompositeDisposable mCompositeDisposable = new CompositeDisposable();

        @Override
        public void onPause() {
            super.onPause();
            mCompositeDisposable.clear();
            //clear will clear all, but can accept new disposable.
            // You can call it on `onPause` or `orDestroyView` events.
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mCompositeDisposable.dispose();
            //dispose will clear all and set isDisposed = true, so it will not accept any new disposable
        }
    }

В своих фрагментах подпишитесь на Observable с помощью метода subscribeWith, который мгновенно даст вам disposable, и этот одноразовый объект вы можете удалить позже в событиях onPause или onDestroy (где хотите)

     public class MyFragment extends BaseFragment {


            @Override
            public void onStart() {
                super.onStart();
                Disposable disposable = m_psUpdatedDays.observeOn(AndroidSchedulers.mainThread())
                        .subscribeWith(new DisposableObserver<List<Long>>() { // Use `subscribeWith` instead of `subscribe`, which will give you back the disposable , which can be disposed later
                            @Override
                            public void onNext(List<Long> longs) {
                                // Update Fragment UI here
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
                mCompositeDisposable.add(disposable); // add the disposable to the disposable list
            }
        }
person Sarath Kn    schedule 14.06.2018
comment
Большое спасибо. Не могли бы вы объяснить разницу между использованием такого CompositeDisposable с subscribeWith и сохранением ссылки на Disposable, переданный в onSubscribe? Я реализовал последнее, и, похоже, он работает так, как должен. Есть ли преимущество в использовании CompositeDisposable по сравнению с List<Disposable>? - person Daniel F; 14.06.2018
comment
Я читал на GitHub комментарий, в котором говорится, что dispose () означает, что вы больше не сможете добавлять одноразовые предметы в этот составной одноразовый объект, clear () означает, что вы можете - он просто очищает одноразовые предметы, которые в настоящее время хранятся в экземпляре. .. Должен ли я затем использовать .clear() вместо .dispose() в методе onStop, поскольку onStart добавит новый Disposable к уже используемому CompositeDisposable при повторном вызове (т.е. приложение переходит в фоновый режим, а затем возобновляет работу)? - person Daniel F; 14.06.2018
comment
используя CompositeDisposable с subscribeWith, и ваша реализация практически одинакова. Но CompositeDisposable становится удобным, когда у вас более одной подписки. CompositeDisposable может хранить все ваши расходные материалы и отказаться от подписки за один шаг. Также subscribeWith сокращает один метод в обратном вызове вашего наблюдателя void onSubscribe(Disposable d), так что ваш наблюдатель становится коротким - person Sarath Kn; 14.06.2018
comment
Должен ли я затем использовать .clear () вместо .dispose () в методе onStop, поскольку onStart добавит новый объект Disposable к уже используемому CompositeDisposable - Да. Также вы можете вызвать dispose() во время onDestroy, как я показал в коде, поскольку впоследствии у вас не может быть новых одноразовых предметов. - person Sarath Kn; 14.06.2018