RxJava+Retrofit,在联网返回后如何先进行统一的判断?

最近在学习rxjava,首先用于联网部分。数据为json格式。 json格式固定为: { "ResultMessage":null, "ResultCode":0, "Data":{} } 然后我希望联网返回数据先行进行ResultCode判断 起先我想要在rxjava的“链”中throw 一个自定义的Error,让Subscriber的onError方法捕捉到。结果发现行不通。不允许这样写。 用single操作符,里面写上 .single(new Func1<LevelListBean, Boolean>() { @Override public Boolean call(LevelLis…
关注者
179
被浏览
14608
// UPDATE AT 2016/12/30
之前那种方式还是有很多问题的,现在项目中用了自我感觉更好的一种方式:
1. 使用 Interceptor 对结果进行拦截
2. 拦截后的结果进行预处理(只解析自己服务端定义的状态码、错误信息等),如果为错误信息,抛出定义的和业务逻辑的异常。
3. 调用接口的时候,直接对异常进行处理。同时也对没有处理的异常已经统一的默认处理定义(例如错误在没有 catch 的时候都直接 toast 提示,需要特殊处理的地方直接 catch 就好了)。
这样处理感觉更直观一下,下面是以前的答案内容,仅供参考。

我们也是刚开始在一个项目中用 Rx + Retrofit,这个问题应该是比较常见的,我们的处理方式可能不是最好的,把详细些的流程介绍一下吧。

1. 首先定义带泛型的返回结果,Retrofit API 的原生结果映射为这种形式:

class Result<T> {
    String ResultMessage;
    int ResultCode;
    T Data; 
}

2. 处理错误的方法和 @朱诗雄 前辈方法差不多,放到作为静态方法放到 RetroUtil 里,这里 ApiException 为自己定义的一个异常,放入错误码和错误信息(错误码不止一个):

static <T> Observable<T> flatResult(Result<T> result) {
    return Observable.create(subscriber -> {
            switch (result.ResultCode) {
                case Constants.SUCCESS_CODE:
                    subscriber.onNext(result.Data);
                    break;
                case Constants.ERROR_CODE:                     
                    subscriber.onError(new ApiException(result.ResultCode, result.ResultMessage);
                    break;
                default:
                    // ...
            }
            subscriber.onCompleted();
        }
    });
}

3. 在 API 包装类对于上述 Result<T> 格式的返回结果,统一调用 flatMap(RetroUtil::flatResult) 后的 API。这样每个 API 的返回结果就是 Observable<Data> 的形式并且在 errorHandler 中统一处理错误了。

// 接口方法
Observable<Result<User>> getUserInfo();

// 包装后的方法
Observable<User> getUserInfo() {
    return mApi.getUserInfo.flatMap(RetroUtil::flatResult);
}

// 调用时
apiWrapper.getUserInfo()
    .subscrible(user -> {
        // 处理正常逻辑
    }, error -> {
        // 处理错误逻辑和异常,这里封装时通常也会统一处理,
        // 提供一个默认的 Action1<Throwable> 参数,弹出
        // throwable 的 message 打印日志等
    });