retrofit2+rxJava2实现我的网络通讯

Retrofit2+RxJava2实现网络通讯

​ 在写这篇文章之前,其实内心是纠结的。因为网上类似的文章有很多,但是个人觉得还是存在一些问题。所以还是打算纪录一下自己在项目中是如何应用的,以便他人参考。

1,明确和服务端交互的数据格式,进一步明确服务端提供的是RESTful风格的微服务,客户端接收的content-type是JSON格式并且具体的响应格式为:

{
status:xxx
msg: xxx
data: xxx
}

这里我稍作解释下,为什么不采用http code,因为多数业务http code是不能满足需求的,所以客户端仅解析http code为200的响应,请求结果的业务状态由status_code判定,data是业务bean实体,虽稍违RESTful理念,但实属无奈。

2,跟后台服务端有了上述约定后,便可开始构建本地网络框架了。一般在项目中我将net层归纳到MVP中的data层中,

data层由网络、文件、数据库组成,presenter只需要向data层获取数据即可。为此客户端采用square开源的retrofit组件和okhttp组件, 这两个组件都是市场比较认可的,我在net层引入并稍作扩展。retrofit组件提供的两个接口需要简单介绍一下。

CallAdapter

`

Retrofit.Builder()
        .baseUrl(baseUrl)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

`

Converter

实现该接口可以将http response body转换成我们想要的格式。规约中http请求返回的content-type
为JSON,那么这里直接使用Gson作为转换器。

`

Retrofit.Builder()
        .baseUrl(baseUrl)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

`

其次具体响应的JSON格式已规定好,为此客户端定义基础响应类型DataResponse来匹配。

`

public class DataResponse<T> {
    //状态码
    @SerializedName("status")
    boolean status;
    @SerializedName("msg")
    String message;
    //数据
    @SerializedName("data")
    T data;
}

`

然后是日志拦截器,需要查看服务器返回的数据,方便本地调试。

`

public class LoggerInterceptor implements HttpLoggingInterceptor.Logger {
    private static final String TAG = LoggerInterceptor.class.getSimpleName();
    @Override
    public void log(String message) {
        try {
            new JsonParser().parse(message);
            if (!TextUtils.isEmpty(message)) {
                Logger.t(TAG).json(message);
            }
        } catch (JsonSyntaxException e) {
            Logger.t(TAG).d(message);
        }
    }
}

`

接着将okhttp关联至retrofit

`

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new LoggerInterceptor());
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(loggingInterceptor)
        .connectTimeout(NetworkConfig.REQUEST_TIME_OUT_DURATION, TimeUnit.SECONDS)
        .build();

return new Retrofit.Builder()
        .baseUrl(baseUrl)
        .client(okHttpClient)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

`

好了,以上流程基本上都是常规套路。最后我们需要定义访问服务器的接口,然后便可以轻松的访问服务器了。

`

interface ApiServer{
    @GET("getBillUpState.do")
    Observable<DataResponse<BillState>> queryBillsState(
            @Query("orgId") String orgId
            , @Query("billType") String billType
            , @Query("billId") String billId
    );
}

`

通过返回的数据可以看出,我们通过服务器返回的是一个Observable

public final class ResponseFlatResult {
    public static <T> Observable<T> flatResult(final DataResponse<T> result) {
        return Observable.create(new ObservableOnSubscribe<T>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<T> subscriber) throws Exception {
                 switch (result.getStatus()) {
                    case NetworkConfig.SUCCESS_CODE://自定义的返回成功码
                        subscriber.onNext(result.getData());
                        break;
                    case NetworkConfig.ERROR_CODE://自定义业务错误,可以通过自定义的异常传递到P层进行处理
                        subscriber.onError(new BusinessException(result.getMessage()));
                        break;
                    default:
                        subscriber.onError(new Exception(result.getMessage()));
                        break;
                }
                 subscriber.onComplete();
            }
        });
    }

}

`

最后,只需要一个flatMap操作符,就能轻松的实现数据转换。

`

public Observable<BillState> billState(String type, String id) {
    return mApiServer.queryBillsState(UserEntity.getInstance().getOrgId(), type, id)
            .flatMap(new Function<DataResponse<BillState>, ObservableSource<BillState>>() {
                @Override
                public ObservableSource<BillState> apply(DataResponse<BillState> booleanDataResponse) throws Exception {
                    return ResponseFlatResult.flatResult(booleanDataResponse);
                }
            });
}

`

这里我深深的感受到了RxJava 给项目带来的便利。各种操作符提高了工作效率和简介的代码,不知不觉RxJava已经贯穿了整个项目中。

猜你喜欢

转载自blog.csdn.net/qq_23186653/article/details/79469020