如何共享创建的Observable?

时间:2016-06-29 17:27:06

标签: android rx-java rx-android

我创建了一个Observable,它发出ViewPager's positionOffset

public Observable<Float> observable() {

    return Observable.create(new Observable.OnSubscribe<Float>() {

        @Override
        public void call(final Subscriber<? super Float> subscriber) {

            if (viewPager == null) {
                if (!subscriber.isUnsubscribed()) {
                    subscriber.onError(new IllegalStateException("viewPager is null"));
                }
                return;
            }

            final ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {

                @Override
                public void onPageScrolled(final int position,
                                           final float positionOffset,
                                           final int positionOffsetPixels) {

                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onNext(positionOffset);
                    }
                }

                @Override
                public void onPageSelected(final int position) {

                }

                @Override
                public void onPageScrollStateChanged(final int state) {

                }
            };
            viewPager.addOnPageChangeListener(listener);

            subscriber.add(Subscriptions.create(() -> viewPager.removeOnPageChangeListener(listener)));
        }
    });
}

它到目前为止有效。

但是对于每个订阅,它会创建一个新的ViewPager.OnPageChangeListener并将其添加到ViewPager。

有没有一种方法可以让所有订阅共享同一个Observable,而ViewPager只有一个Listener?

2 个答案:

答案 0 :(得分:0)

如果您有多个订阅者,可以使用Observable.share()这个不错的选项,如果迟到的订阅者可能会丢失一些通知,请不要介意。

如果您希望所有订阅者都看到相同的通知,请使用Observable.publish() - 它将返回ConnectableObservable,它会在调用connect()方法后开始发出项目。所以你可以做到

connectable = originalObservable.publish();
connectable.subscribe(observer1);
connectable.subscribe(observer2);
connectable.connect();

答案 1 :(得分:0)

您可以使用Connectable observables。 例如,下面的代码模拟无限(永不完成)事件流:

Observable<Float> o = Observable.concat(Observable.just(1f,2f,3f), Observable.never());

您可以使用带有refCount的重播创建一个可连接的observable,它将缓存最后一个值:

Observable<Float> shared = o.replay(1).refCount();

第一个订阅者将使可观察的“热”并强制它生成项目:

shared.subscribe(new Action1<Float>() {

  @Override
  public void call(Float t) {
    System.out.println("o1:" + t);

  }

});
Thread.sleep(1000);

第二个observable可能会在一段时间后连接到它,并将从最新发出的项目开始:

shared.subscribe(new Action1<Float>() {

  @Override
  public void call(Float t) {
    System.out.println("o2:" + t);

  }

});

Thread.sleep(1000);

输出:

o1:1.0
o1:2.0
o1:3.0
o2:3.0