使用FlatMap的RxAndroid间隔触发CALL两次而不是一次

时间:2016-03-22 11:01:12

标签: android rx-java observable rx-android

CODE

 heartBeatSub = Observable.interval(HEARTBEAT_INTERVAL, TimeUnit.SECONDS)
            .flatMap(new Func1<Long, Observable<Notification<Response>>>() {
                @Override
                public Observable<Notification<Response>> call(Long aLong) {
                    return api.requestHeartBeat(vehicleId).materialize();
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Notification<Response>>() {
                @Override
                public void call(Notification<Response> responseNotification) {
                    Log.i("HEARTBEAT_INTERVAL", "Response from HEARTBEAT");
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    // TODO: 22/03/16 ADD ERROR HANDLING
                }
            });

问题

我的call方法会被触发两次,而不是每个时间间隔一次。

03-22 11:57:47.236 28078-28078/com.app I/HEARTBEAT_INTERVAL: Response from HEARTBEAT
03-22 11:57:47.876 28078-28078/com.app I/HEARTBEAT_INTERVAL: Response from HEARTBEAT

第一个我携带:Method threw 'java.lang.NullPointerException' exception. Cannot evaluate rx.Notification.toString() 并称为onNext

第二个是正常Response。 并称为onCompleted

========固定代码==========

借助@Daniel Lew帮助我修复了我的代码,现在它正常工作

  private void triggerHeartBeat(final String vehicleId) {
    heartBeatSub = Observable.interval(HEARTBEAT_INTERVAL, TimeUnit.MINUTES)
            .flatMap(new Func1<Long, Observable<Response>>() {
                @Override
                public Observable<Response> call(Long aLong) {
                    return api.requestHeartBeat(vehicleId);
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Response>() {
                @Override
                public void call(Response response) {
                    Log.i("HEARTBEAT_INTERVAL", "Response from HEARTBEAT");
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    // TODO: 22/03/16 ADD ERROR HANDLING
                }
            });

1 个答案:

答案 0 :(得分:4)

你不应该致电materialize()。它会将所有通知(onNext()onCompleted()onError())提升到自己的onNext()来电中,并产生负面影响。

flatMap()内的每个API请求都是完整的Observable,这意味着它同时调用onNext(response)onCompleted()。通常情况flatMap()不会转发onCompleted()(因为interval()尚未完成),但由于您拨打materialize()所有通知都会转发给订阅者。

换句话说,你得到了这个:

  1. 通知(onNext(带有您的回复))
  2. 通知(onCompleted)
  3. 如果你没有使用materialize(),你会得到你想要的东西:

    1. onNext(带有您的回复)。