当Retrofit2+RxJava2遇到为null的返回结果

前言

更新RxJava2之后,就不能在onNext里面发送null值了。但是项目中有些接口,例如发送手机验证码的接口,后台返回过来data就为null。我将请求结果再次进行了一次包装,解决此问题,便在这记录下来。

正题

解决思路很简单,先将返回结果放入另一个对象中,让它可以成功发送出去,最后在回调方法中从此对象中去获取返回结果。

首先提供一个包装返回结果的类:Optional

public class Optional<M> {

    private final M optional; // 接收到的返回结果
    public Optional(@Nullable M optional) {
        this.optional = optional;
    }
    // 判断返回结果是否为null
    public boolean isEmpty() {
       return this.optional == null;
    }
    // 获取不能为null的返回结果,如果为null,直接抛异常,经过二次封装之后,这个异常最终可以在走向RxJava的onError()
    public M get() {
        if (optional == null) {
             throw new NoSuchElementException("No value present");
        }
        return optional;
    }
    // 获取可以为null的返回结果
    public M getIncludeNull() {
       return optional;
   }
}

现在已经可以将返回结果包装起来,然后就可以将这个包装后的对象发送出去,我的封装代码是:

/**
 * http请求结果处理方法
 *
 * @param <T>
 * @return
 */
public static <T> ObservableTransformer<RESTResult<T>, Optional<T>> handle_result() {
    return upstream -> upstream
            .flatMap(new Function<RESTResult<T>, ObservableSource<Optional<T>>>() {
                         @Override
                         public ObservableSource<Optional<T>> apply(@NonNull RESTResult<T> result) throws Exception {
                             if (result.status == RESTResult.SUCCESS) {
                                 // result.transform() 就是将返回结果进行包装
                                 return createHttpData(result.transform());
                             } else if (result.status == RESTResult.SIGN_OUT) {
                                // 登录失效逻辑处理
                                // ... 
                             } else {
                                 // 发送请求失败的信息
                                 String msg = result.message;
                                 return Observable.error(new RxException(msg));
                             }

                             return Observable.empty();
                         }
                     }
            );
}

private static <T> Observable<Optional<T>> createHttpData(Optional<T> t) {

    return Observable.create(e -> {
        try {
            e.onNext(t);
            e.onComplete();
        } catch (Exception exc) {
            e.onError(exc);  
        }
    });
}

最后只需要通过optional.get()或者optional.getIncludeNull()就可以得到请求结果。

推荐阅读更多精彩内容