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…
关注者
173
被浏览
11667
更新:
新发现RxJava有个compose方法,可以不必在外部包裹一层,在之前回答基础上,可以采用以下方式调用:
mApiService.getUserInfo(params...).compose(ApiWrapper::warp)
        .subscribe(data -> {...}, error -> {...})
//以下是原回答

本回答在@twiceYuan的回答的基础上进行了改进
刚开始学着用RxJava,今天也遇到了同样的问题
之前的解决方案参考了@twiceYuan的回答
但我这边的需求要复杂些,除了做同楼主一样的处理,还需要接一些其它的处理(map, filter)什么的,这样的话每次新增一个api,都要在apiWrapper和ApiService里面添加两个几乎一样方法,而且要在wrapper的方法里copy一串一摸一样的处理代码,看起来像这样:
Observable<User> getUserInfo() {
    return mApi.getUserInfo
               .flatMap(RetroUtil::flatResult)
               .map(RetroUtil::mapResult)
               .map(RetroUtil::mapResult2)
               .flatMap(RetroUtil::flatResult2);

}

Observable<User> getUserInfo(String id) {
    return mApi.getUserInfo(id)
               .flatMap(RetroUtil::flatResult)
               .map(RetroUtil::mapResult)
               .map(RetroUtil::mapResult2)
               .flatMap(RetroUtil::flatResult2);

}

Observable<User> getUserInfo(String id, String token) {
    return mApi.getUserInfo(id, token)
               .flatMap(RetroUtil::flatResult)
               .map(RetroUtil::mapResult)
               .map(RetroUtil::mapResult2)
               .flatMap(RetroUtil::flatResult2);

}
这样产生了不少重复劳动,而且看起来不够优雅,经过改进,wrapper类精简到了对外只暴露一个wrap方法,针对不同的参数个数有几个类似的多态函数,代码如下:
public static <R, P1, P2, P3, P4> Observable<R> wrap(P1 p1, P2 p2, P3 p3, P4 p4, Func4<P1, P2, P3, P4, Observable<ResponseBean<R>>> func) {
        return wrap(func.call(p1, p2, p3, p4));
    }

    public static <R, P1, P2, P3> Observable<R> wrap(P1 p1, P2 p2, P3 p3, Func3<P1, P2, P3, Observable<ResponseBean<R>>> func) {
        return wrap(func.call(p1, p2, p3));
    }

    public static <R, P1, P2> Observable<R> wrap(P1 p1, P2 p2, Func2<P1, P2, Observable<ResponseBean<R>>> func) {
        return wrap(func.call(p1, p2));
    }

    public static <R, P1> Observable<R> wrap(P1 p1, Func1<P1, Observable<ResponseBean<R>>> func) {
        return wrap(func.call(p1));
    }

    public static <R> Observable<R> wrap(Func0<Observable<ResponseBean<R>>> func) {
        return wrap(func.call());
    }
    
    public static <R> Observable<R> wrap(Observable<ResponseBean<R>> result) {
        return result.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(RetroUtil::flatResult)
                .map(RetroUtil::mapResult)
                .map(RetroUtil::mapResult2)
                .flatMap(RetroUtil::flatResult2);
    }

这样在外部调用时,只需要:
ApiWrapper.wrap(param1, param2, mApiService::method)
        .subscribe(data -> {...}, error -> {...})

//或者
ApiWrapper.wrap(mApiService.getUserInfo(params...))
        .subscribe(data -> {...}, error -> {...})
这样新增api的时候,只需要在ApiService同往常一样添加一个方法,而不必在ApiWrapper里面copy代码