Retrofit2和Rxjava2封装思路

//ApiService.java
public interface ApiService {


  @POST("app/api")
    Observable<Response2> request2(@Body Request2 request);
    /**
     * Create a new ApiService
     */
    class Factory {
        private Factory() {  }

        public static ApiService createService( ) {
            OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
            builder.readTimeout(10, TimeUnit.SECONDS);
            builder.connectTimeout(9, TimeUnit.SECONDS);

            if (BuildConfig.DEBUG) {
                HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
                interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                builder.addInterceptor(interceptor);
            }

            builder.addInterceptor(new HeaderInterceptor());
            OkHttpClient client = builder.build();
            Retrofit retrofit =
                    new Retrofit.Builder().baseUrl(ApiService.ENDPOINT)
                            .client(client)
                            .addConverterFactory(GsonConverterFactory.create())
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .build();
            return retrofit.create(ApiService.class);
        }
    }
}

使用起来如下

ApiService mApiService = ApiService.Factory.createService();
mApiService.request1(request)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Response1 response) {
                        int code = response.getCode();
                        switch (code) {
                            case 1: //do something
                                break;
                            case -101://do something
                                break;
                            case -102: //do something
                                break;
                            default:
                                break;
                        }
                    }
                });

最终目标封装成如下

    @POST("order/getAllOrders")
    Observable<HttpResult<List<Order>>> postOrderList(@Body OrderRequest request);
           ServiceFactory.orderApi()
                    .postOrderListState(mRequest)
                    .compose(new DefaultTransformer>())
                    .subscribe(new CommonSubscriber>(mContext) {
                        @Override
                        public void onNext(List data) {


                        }

                        @Override
                        protected void onError(ApiException ex) {
                            super.onError(ex);
                            ToastUtil.showShort(mContext, ex.message);
                        }
                    });

提取ApiService的Api类的创建
上面的Factory一起创建一个ServiceFactory

Retrofit2和Rxjava2封装思路_第1张图片

  //https 支持
  HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
        sClient = new OkHttpClient().newBuilder()
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                //设置链接时间
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                //设置拦截器
                .addInterceptor(new HeaderInterceptor())
                .addInterceptor(new TokenInterceptor())
                .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
                .retryOnConnectionFailure(true)
                //断网重连
                .build();
        OkHttpUtils.initClient(sClient);

        sRetrefit = new Retrofit.Builder()
                .client(sClient)
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(MyApplication.getmGson()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

DefaultTransformer封装
首先得了解操作符compose()和flatMap()有啥区别呢。他们都是发射出Observable,是不是就是说他们都可以复用一系列操作符呢?

compose() 是针对 Observable 自身进行变换。

  1. compose()是唯一一个能从流中获取原生Observable
    的方法,因此,影响整个流的操作符(像subscribeOn()和observeOn())需要使用compose(),相对的,如果你在flatMap()中使用subscribeOn()/observeOn(),它只影响你创建的flatMap()中的Observable,而不是整个流。

  2. 当你创建一个Observable流并且内联了一堆操作符以后,compose()会立即执行,flatMap()则是在onNext()被调用以后才会执行,换句话说,flatMap()转换的是每个项目,而compose()转换的是整个流。

  3. flatMap()一定是低效率的,因为他每次调用onNext()之后都需要创建一个新的Observable,compose()是操作在整个流上的。
    Retrofit2和Rxjava2封装思路_第2张图片
    Retrofit2和Rxjava2封装思路_第3张图片

这里没有出错就转成HttpResult出错了就抛出异常

                // 通过对返回码进行业务判断决定是返回错误还是正常取数据    
               if (httpResult.getCode() != ErrorType.SUCCESS) {
                    throw new ServerException(httpResult.getMessage(), httpResult.getCode());
                }
                return httpResult.getData();
 .onErrorResumeNext(new Func1>() {
            @Override
            public Observable call(Throwable throwable) {
                //ExceptionEngine为处理异常的驱动器
                return Observable.error(ExceptionEngine.handleException(throwable));
            }
        });

抛出异常以后再走.onErrorResumeNext 方法

public class ServerException extends RuntimeException {
    // 异常处理,为速度,不必要设置getter和setter
    public int code;
    public String message;

    public ServerException(String message, int code) {
        super(message);
        this.code = code;
        this.message = message;
    }
}
public class ExceptionEngine {
    //对应HTTP的状态码
    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;

    public static ApiException handleException(Throwable e) {
        ApiException ex;
        if (e instanceof HttpException) {             //HTTP错误
            HttpException httpException = (HttpException) e;
            ex = new ApiException(e, ErrorType.HTTP_ERROR);
            switch (httpException.code()) {
                case UNAUTHORIZED:
                    ex.message = "当前请求需要用户验证";
                    break;
                case FORBIDDEN:
                    ex.message = "服务器已经理解请求,但是拒绝执行它";
                    break;
                case NOT_FOUND:
                    ex.message = "服务器异常,请稍后再试";
                    break;
                case REQUEST_TIMEOUT:
                    ex.message = "请求超时";
                    break;
                case GATEWAY_TIMEOUT:
                    ex.message = "作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应";
                    break;
                case INTERNAL_SERVER_ERROR:
                    ex.message = "服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理";
                    break;
                case BAD_GATEWAY:
                    ex.message = "作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应";
                    break;
                case SERVICE_UNAVAILABLE:
                    ex.message = "由于临时的服务器维护或者过载,服务器当前无法处理请求";
                    break;

                default:
                    ex.message = "网络错误";  //其它均视为网络错误
                    break;
            }
            return ex;
        } else if (e instanceof ServerException) {    //服务器返回的错误
            ServerException resultException = (ServerException) e;
            ex = new ApiException(resultException, resultException.code);
            ex.message = resultException.message;
            return ex;
        } else if (e instanceof JsonSyntaxException) {
//            ex = new ApiException(e, ErrorType.TOKEN_INVALID);
//            ex.message = "Token失效";            //均视为解析错误
            ex = new ApiException(e, ErrorType.PARSE_ERROR);
            ex.message = "返回数据错误";            //均视为解析错误
            return ex;
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            ex = new ApiException(e, ErrorType.PARSE_ERROR);
            ex.message = "解析错误";            //均视为解析错误
            return ex;
        } else if (e instanceof ConnectException || e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException) {
            ex = new ApiException(e, ErrorType.NETWORD_ERROR);
            ex.message = "连接失败";  //均视为网络错误
            return ex;
        } else {
            ex = new ApiException(e, ErrorType.UNKNOWN);
            ex.message = "未知错误";          //未知错误
            return ex;
        }
    }

最后再走CommonSubscriber.error

你可能感兴趣的:(android开发,Rxjava2,Retrofit2)