通过PublishSubject在onNext中传递null并在RxJava中过滤该响应

时间:2018-06-21 07:39:44

标签: java android rx-android

我有这样的代码:

  getLocationObservable() //this observable returns via PublishSubject the location
          .filter(location -> {
              .....
              Here I want to be able to get a null value for the location
          })
         .flatMap(location -> anotherObservable()
                             .subscribeOn(Schedulers.io())
                             .observeOn(AndroidSchedulers.mainThread()))
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe( new Observer<........

在Location类中是这样的:

 private PublishSubject<Location> locationPublishSubject = PublishSubject.create();

    public Observable<Location> getLocationObservable() {
        return locationPublishSubject;
    }

    and then...
    locationPublishSubject.onNext( foundLocation);

现在,getLocationObservable基于PublishSubject,它通过onNext返回位置。然后在filter运算符中对其进行分析。但是,有时找不到Location,并且它传递null。但是在onNext中传递null会导致崩溃。 更具体地说,我得到:UndeliverableException: java.lang.Throwable 怎么解决?

2 个答案:

答案 0 :(得分:1)

Rx不能与null一起使用,最终会引发异常。 您可以在此处使用Wrapper模式。

科特林语中的示例

class Wrapper<T>(val value: T?)

修改您的主题以发出包装在包装器类中的位置。在过滤选项中检查其是否包含null,例如

.filter{ it.value != null }

Java示例

添加课程Wrapper

public class Wrapper<T> {
    public final T value;

    public Wrapper(T value) {
         this.value = value;
    } 
}

然后在发射新位置并对其进行过滤时使用它。

public Observable<Location> getLocationObservable() {
        return locationPublishSubject;
}
and then...
locationPublishSubject.onNext(new Wrapper(foundLocation));

.filter(wrapper -> {
    wrapper.value != null;
})

或者,如果可能的话,您可以跳过发射位置(如果可能)。

答案 1 :(得分:0)

您可以通过执行以下操作来实现:

我假设您的foundLocation变量的类型为Location,其中包含2个属性lat和lng。

在这种情况下,您可以检查找到的位置是否为空,如果为空,则将其替换为包含lat和lng且值不可能的对象:

if(foundLocation == null) {
   foundLocation  = new Location(-1000, -1000);
}
locationPublishSubject.onNext( foundLocation);

然后在代码的onNext中,您可以检查lat和lng是否都等于-1000:

if(foundLocation.getLatitude() == -1000 && foundLocation.getLongitude() == -1000) {
    // here you have a null location
}