【问题标题】:Unsubscribing from RxJava2/RxAndroid PublishSubject从 RxJava2/RxAndroid PublishSubject 退订
【发布时间】:2018-06-13 18:32:14
【问题描述】:

我正在尝试用 RxAndroid 替换 EventBus。

我希望可分页片段订阅/取消订阅事件源,这些片段的创建和丢弃速度相对较快,具体取决于用户滑动到新页面的速度。

在 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);
}

并通过在 Fragment 的 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() {}
});

我的问题是,当 Fragment 的 onStop 方法被系统调用时,如何取消订阅这个新的 Observer?

我是否需要存储我在onSubscribe 中获得的Disposable 对象,然后在onStop 方法中对其调用.dispose()

【问题讨论】:

标签: rx-java2 publish-subscribe rx-android event-bus


【解决方案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
        }
    }

在您的 Fragment 中,使用 subscribeWith 方法订阅 Observable,它会立即为您提供 disposable,并且您可以稍后在 onPauseonDestroy 事件中处置此一次性物品(无论​​您想要什么)

     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
            }
        }

【讨论】:

  • 非常感谢。您能否解释一下使用subscribeWithsubscribeWith 与存储对Disposable 的引用之间的区别@ 987654332@?我已经实现了后者,它似乎可以正常工作。使用CompositeDisposableList&lt;Disposable&gt; 相比有什么好处吗?
  • 我在 GitHub 上阅读了一条评论,指出“dispose() 意味着您将无法再将一次性用品添加到该复合一次性用品中,clear() 意味着您可以 - 它只是清除当前保存在实例中的一次性物品。”。然后我应该在onStop 方法中使用.clear() 而不是.dispose(),因为onStart 将在再次调用它时将一个新的Disposable 添加到已经使用的CompositeDisposable(即应用程序进入后台并且稍后恢复)?
  • 将 CompositeDisposable 与 subscribeWith 一起使用,您的实现实际上是相同的。但是CompositeDisposable 在您拥有多个订阅时会变得很方便。 CompositeDisposable 可以容纳您所有的一次性用品,并一步退订。另外subscribeWith 减少了观察者回调void onSubscribe(Disposable d) 中的一种方法,以便您的观察者变短
  • 我是否应该在 onStop 方法中使用 .clear() 而不是 .dispose() ,因为 onStart 将向已使用的 CompositeDisposable 添加一个新的 Disposable - 是的。你也可以在onDestroy 期间调用dispose(),正如我在代码中显示的那样,因为之后你不能有任何新的一次性用品
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 2017-11-21
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多