获取错误“;可调用的返回null“;使用RxJava2时
我在android项目中使用RxJava2 我正在使用以下代码创建可观察的获取错误“;可调用的返回null“;使用RxJava2时,java,android,rx-java,reactive-programming,rx-java2,Java,Android,Rx Java,Reactive Programming,Rx Java2,我在android项目中使用RxJava2 我正在使用以下代码创建可观察的 public Observable<AlbumDetails> loadAlbumFromAlbumId(final String albumId) { return Observable.fromCallable(new Callable<AlbumDetails>() { @Override public AlbumDetails call() thro
public Observable<AlbumDetails> loadAlbumFromAlbumId(final String albumId) {
return Observable.fromCallable(new Callable<AlbumDetails>() {
@Override
public AlbumDetails call() throws Exception {
AlbumDetails albumDetails = getAlbumDetails(albumId);
return albumDetails;
});
}
公共可观察loadAlbumFromAlbumId(最终字符串albumId){
返回Observable.fromCallable(newcallable()){
@凌驾
公共AlbumDetails调用()引发异常{
AlbumDetails AlbumDetails=getAlbumDetails(albumId);
返回详细信息;
});
}
从可观察的角度来看,我在一次性观察者的onError方法中得到以下错误
Callable返回空值
这在使用RxJava时不会发生。如wiki中所示:
RxJava 2.x不再接受null值。将null作为流元素会立即导致NullPointerException
,因此会调用onError方法
这样做主要是为了避免由于应用程序中的NullPointerException
而导致崩溃
我用一种相当简单的方法解决了这个问题。
我检查该值是否为null,如果为null,则用占位符对象替换null
其他更复杂的方法也可以解决这个问题,但对于我的用例来说,这种简单的方法已经足够了。rxjava2.x不再接受空值而不实现错误处理程序
示例
Observable.fromCallable(() -> null)
.subscribe(System.out::println, Throwable::printStackTrace);
Observable.just(1).map(v -> null)
.subscribe(System.out::println, Throwable::printStackTrace);
针对您的问题的解决方案
Observable.fromCallable(() -> null)
.subscribe(System.out::println, Throwable::printStackTrace);
Observable.just(1).map(v -> null)
.subscribe(System.out::println, Throwable::printStackTrace);
当您调用/订阅此方法时,请执行以下操作
Observable<AlbumDetails> testObservable= Observable.create(emitter -> { ... });
testObservable.subscribe(t -> System.out.print(t),Throwable::printStackTrace);
Observable testObservable=Observable.create(发射器->{…});
testObservable.subscribe(t->System.out.print(t),Throwable::printStackTrace);
您还可以将返回值包装在可选的(Java 8)中,并使用Optional.isPresent()和Optional.get()将其映射到订阅中。我以前有这样的代码:
Observable<R> obs = Observable.fromCallable(this::work);
public Observable<AlbumDetails> loadAlbumFromAlbumId(String albumId) {
return Maybe.fromCallable(() -> getAlbumDetails(albumId))
.onErrorComplete()
.toObservable();
};
inline fun <T> runInSingle(
crossinline block: () -> T,
crossinline callback: (T?) -> Unit,
crossinline onError: (Throwable) -> Unit) {
Single.fromCallable {
return@fromCallable block().toNullableObject()
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { result, error ->
if (error != null) {
onError(error)
} else {
callback(result.value)
}
}
}
fun <T> T.toNullableObject(): NullableObject<T> = NullableObject(this)
这样,最终消费者——观察者——只有在work()返回任何内容时才会启动。如果work()返回null,则与订阅空观察者相同;什么也不会发生
方法2
Observable obs=可观测的。创建(e->{
R=功();
如果(r!=null){
e、 onNext(r);
}
e、 onComplete();
});
方法3:
将每个排放包装在一个可选的=坏主意,原因有很多
主要是因为我只在我的API中使用可选的,若它是预期的,并且有点“正常”场景是,您不时会得到一个null。如果null不是预期的或非常罕见,可能是由于同一消费者执行的另一个API调用的直接结果,那么我返回null,让消费者在这些异常情况下处理它,而不是让每个消费者处理所有可选的问题。假设getAlbumDetails(albumId)
方法返回null
如果数据不可用或出错,并且您愿意在这种情况下优雅地完成流,您可以使用如下方法:
Observable<R> obs = Observable.fromCallable(this::work);
public Observable<AlbumDetails> loadAlbumFromAlbumId(String albumId) {
return Maybe.fromCallable(() -> getAlbumDetails(albumId))
.onErrorComplete()
.toObservable();
};
inline fun <T> runInSingle(
crossinline block: () -> T,
crossinline callback: (T?) -> Unit,
crossinline onError: (Throwable) -> Unit) {
Single.fromCallable {
return@fromCallable block().toNullableObject()
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { result, error ->
if (error != null) {
onError(error)
} else {
callback(result.value)
}
}
}
fun <T> T.toNullableObject(): NullableObject<T> = NullableObject(this)
公共可观察loadAlbumFromAlbumId(字符串albumId){
返回Maybe.fromCallable(()->getAlbumDetails(albumId))
.onErrorComplete()
.toObservable();
};
为了更好的可读性,我用lambda替换了匿名类,但您当然可以保持原样。我提出了以下解决方法:
首先创建了一个包装器类:
class NullableObject<T>(val value: T?)
在编译时不给出错误,在调试apk中也不给出错误,但让您尝试一下已发布的apk。