为什么这个observable只发出一个值

时间:2014-10-29 03:33:33

标签: android rx-java

我有以下代码基于@ a.bertucci在Emit objects for drawing in the UI in a regular interval using RxJava on Android提供的示例,其中我使用Timer压缩Observable。当我通过调用processDelayedItems()触发订阅时,压缩的Observable中的代码[A]只执行一次,并且一个项目被发送到[B]。我希望代码[A]在触发后连续运行并且每隔1500毫秒继续发射一次,但显然它只在这里运行一次。

private static void processDelayedItems() {

    Observable.zip(
            Observable.create(new Observable.OnSubscribe<Object>() {

                @Override public void call(Subscriber<? super Object> subscriber) {
                    // [A] this code is only called once
                    subscriber.OnNext(o)
                }

            }),
            Observable.timer(1500, 1500, TimeUnit.MILLISECONDS), new Func2<Object, Long, Object>() {
                @Override public Object call(Object entity, Long aLong) {
                    return entity;
                }
            }
    )
    .subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Object>() {

                @Override public void call(Object entity) {
                    // ... and accordingly one item is emitted [B]
                }

            }, new Action1<Throwable>() {

                @Override public void call(Throwable throwable) {
                    throwable.printStackTrace();
                }

            }, new Action0() {

                @Override public void call() {

                }

            });

}
  1. 有人能看到我在这里遇到的问题吗?是否需要从函数外部引用Observable以使其保持活动更长时间?它是由GC(Android)收集的吗?问题是函数是静态的吗?

  2. Observables的实时规则是什么?是否有任何最佳实践应该引用更长时间运行的Observables以及它们是否可以是静态的?在我的测试中,我注意到它并不重要,但是当涉及计时器时,它可能就在这里。

  3. -

    更正代码[尚未运行]:

    • 添加了repeat()

      Observable.zip(
              Observable.create(new Observable.OnSubscribe<Object>() {
      
                  @Override public void call(Subscriber<? super Object> subscriber) {
                      // [A] this code is only called once
                      subscriber.OnNext(o);
                      subscriber.OnCompleted();
                  }
      
              }).repeat(Schedulers.newThread()),
              Observable.timer(1500, 1500, TimeUnit.MILLISECONDS), new Func2<Object, Long, Object>() {
                  @Override public Object call(Object entity, Long aLong) {
                      return entity;
                  }
              }
      )
      .subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
              .subscribe(new Action1<Object>() {
      
                  @Override public void call(Object entity) {
                      // ... and accordingly one item is emitted [B]
                  }
      
              }, new Action1<Throwable>() {
      
                  @Override public void call(Throwable throwable) {
                      throwable.printStackTrace();
                  }
      
              }, new Action0() {
      
                  @Override public void call() {
      
                  }
      
              });
      

2 个答案:

答案 0 :(得分:1)

您需要repeat来生成无限的Observable。如,

    Observable.create(new Observable.OnSubscribe<Object>() {

        @Override public void call(Subscriber<? super Object> subscriber) {
            // [A] this code is only called once
            if (!subscriber.isUnsubscribed()) {
                subscriber.onNext(o);
            }
            if (!subscriber.isUnsubscribed()) {
                subscriber.onCompleted();
            }
        }

    }).repeat(Schedulers.newThread());
  

是否需要从函数外部引用Observable以使其保持活动更长时间?它是由GC(Android)收集的吗?问题是函数是静态的吗?

由于您使用Schedulers.newThread()timer,因此会有一些其他线程引用您的Observable。你不需要更多的工作。

  

Observables的实时规则是什么?是否有任何最佳实践应该引用更长时间运行的Observables以及它们是否可以是静态的?在我的测试中,我注意到它并不重要,但也许在这里,当涉及计时器时。

你是对的。这没关系。

答案 1 :(得分:1)

关于你的评论,为简单起见,你可以这样做,

Observable.timer(1500, 1500, TimeUnit.MILLISECONDS)
        .flatMap(new Func1<Long, Observable<Object>>() {
            @Override
            public Observable<Object> call(Long aLong) {
                String o = "0";
                return Observable.from(o);
            }
        })
        .subscribe(new Action1<Object>() {
            @Override
            public void call(Object aLong) {
                System.out.println(aLong);
            }
        });

在这里,您仍然可以获得计时器的好处,而不会在顶部添加拉链/重复。它仍然有点冗长,但它有点简单。