RxJava和长时间运行的监听器

时间:2017-04-12 12:54:47

标签: java android rx-java2

好的,所以我是RxJava2的新手(好吧,我也不知道RxJava)并且正在尝试使用RxJava2和MVP结构开发Android应用程序。

在该应用程序中,我正在对使用侦听器的库进行异步调用。 我使用"标准"设置了监听器。 setListener / registerListener方法。

其中一种方法是返回值"实时" - >我调用了我的库的start()方法,然后在每次修改列表时都会通知我的监听器(当有一个项目的添加/删除时)。

我没有真正掌握如何使用RxJava实现此行为,因为侦听器是在发射器/订阅者的定义中订阅的? 我应该在哪里宣布听众?我应该在哪里取消订阅?我应该使用什么对象?

我使用Nucleus启动了开发,但可以切换到另一个样板或自己做一个。

这是一些说明我问题的伪代码:

之前

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    mMyLib.setListener(this);
    mMyLib.startDiscovery();
}

@Override
public void itemListChanged(List<Dummy> items) {
    // update the UI with the list items
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mMyLib.setListener(null);
}

在演示者中使用Nucleus

只要我的活动/演示者还活着,我应该在哪里取消订阅?我甚至使用正确的语法/对象吗?

private static final int REQUEST_ITEMS = 1;
private PublishSubject<Integer> pageRequests = PublishSubject.create();

...

@Override
public void onCreate(Bundle savedState) {
    super.onCreate(savedState);

    restartableReplay(REQUEST_ITEMS,
            () -> Observable.create(e ->
                    {
                        mMyLib.setListener(new MyLib.Listener() {
                            @Override
                            public void itemListChanged(List<Dummy> items) {
                                Log.d(TAG, "meh itemListChanged");
                                e.onNext(items);
                                e.onComplete();
                            }
                        });
                        mMyLib.startDiscovery();
                    }
            )
            ,
            MainFragment::onItems,
            MainFragment::onNetworkError);
}

void request() {
    start(REQUEST_ITEMS);
}

1 个答案:

答案 0 :(得分:1)

你是正确的方向,这是用RxJava包装异步回调的有效方法,几条评论:

  • 你在e.onComplete()打电话itemListChanged,这是错误的,因为它会结束你的Observable序列,你可能根本不需要拨打onComplete(),它永远不会结束来自外部来源的通知,或者在真实的通知结束时调用它一次(外部源完成以生成项目),不要将它与取消订阅源混淆。
  • 要取消订阅逻辑,您应该在create()中定义,使用取消逻辑(e.setCancellable()或任何其他清理资源代码)调用mMyLib.setListener(null)
  • 在这种情况下,您似乎只有1个订阅者,但在其他方面考虑使用share(),以便拥有可以多播到多个订阅者的“热门”Observable
  • 至于Nucleus库,据我记得restartableReplay,将缓存你的Observable重放发出的项目,这可能是错误的这种“热门”事件流(除非你需要重播可能是最后一次发射或其​​他事情),另外,缓存会有问题,因为你将失去取消订阅能力,所以一定要在这里使用Nucleus。
  

只要我的活动/演示者还活着,我应该在哪里取消订阅,如果我想接收列表的修改?我甚至使用正确的语法/对象吗?

您只需取消订阅即可停止接收通知的任何地方,无论是onStop()还是onDestory(),取决于您。