Retrofit2+RxAndroid+RxJava2 封装(2)

Retrofit2+RxAndroid+RxJava2 封装

1 首先在项目中配置config ,配置所需要的每个依赖库的version,统一管理方便维护

  • 版本号
def okhttp3Version = "3.10.0"
def retrofitVersion = "2.4.0"
def rxjava = "3.0.0"
def rxandroid = "2.1.0"
def logging_interceptor = "3.6.0"

  • 仓库连接
 dependencies = [
       
            "okhttp3"               : "com.squareup.okhttp3:okhttp:${okhttp3Version}",
            "retrofit"              : "com.squareup.retrofit2:retrofit:${retrofitVersion}",
            "converter-gson"        : "com.squareup.retrofit2:converter-gson:${retrofitVersion}",
            "adapter-rxjava2"       : "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}",
            "rxjava"                : "io.reactivex.rxjava3:rxjava:${rxjava}",
            "rxandroid"             : "io.reactivex.rxjava2:rxandroid:${rxandroid}",
            "logging-interceptor"   : "com.squareup.okhttp3:logging-interceptor:${logging_interceptor}"
    ]
  • 在项目build 中集成
    api rootProject.ext.dependencies["retrofit"]
    implementation rootProject.ext.dependencies["rxjava"]
    implementation rootProject.ext.dependencies["okhttp3"]
    implementation rootProject.ext.dependencies["converter-gson"]
    implementation rootProject.ext.dependencies["adapter-rxjava2"]
    implementation rootProject.ext.dependencies["logging-interceptor"]
    implementation rootProject.ext.dependencies["rxandroid"]

2 开始搭建

  • step1 Client

Client 的作用就是创建自己需要的 okhttpclient(包括 是否支持 https,公共参数拦截器等)
超时时间 可以自己设定。

public class RetrofitClient {

    private static volatile RetrofitClient retrofitClient;
    private static final int DEFAULT_TIME_OUT = 15;

    private OkHttpClient okHttpClient;
    private Retrofit retrofit;
    private String url;


    public void initRetrofit(String url) {
        this.url = url;
    }

    /**
     * retrofit 初始化build
     */
    private RetrofitClient() {
    }

    /**
     * 单例
     *
     * @return
     */
    public static synchronized RetrofitClient getInstance() {
        if (retrofitClient == null) {
            synchronized (RetrofitClient.class) {
                retrofitClient = new RetrofitClient();
                return retrofitClient;
            }
        }
        return retrofitClient;
    }

    /**
     * 创建httpClient
     * 支持https
     *
     * @return
     */
    private OkHttpClient createOkHttpClient() {
        //设置请求头拦截器
        //设置日志拦截器
        if (null == okHttpClient) {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT);
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);


            //根据需求添加不同的拦截器
            okHttpClient = new OkHttpClient
                    .Builder()
                    .addInterceptor(httpLoggingInterceptor)
                    .connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
                    .writeTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
                    .readTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
                    .connectionPool(new ConnectionPool(8, 10, TimeUnit.SECONDS))
                    .retryOnConnectionFailure(true)
                    .build();
        }
        return okHttpClient;
    }


    /**
     * Retrofit Client create
     */
    public <T> T create(Class<T> interfaceServer) {
        if (null == retrofit) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(url)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(createOkHttpClient())
                    .build();
        }
        if (interfaceServer == null) {
            throw new RuntimeException("The Api InterfaceServer is null!");
        }
        return retrofit.create(interfaceServer);
    }
}
  • step2 BaseResponse

数据entity base, 客户端服务器约定 errMsg、 errCode

public class BaseResponse<T> implements Serializable {

    private boolean success;
    private String errMsg;
    private int errCode;
    private T data;
  • step3 ResponseTransformer 分离器

分离器的作用是将正常数据和异常分离出来各种处理

  • 先看看非服务器异常类
public class CustomException {
   /**
    * 未知错误
    */
   public static final int UNKNOWN = 1000;

   /**
    * 解析错误
    */
   public static final int PARSE_ERROR = 1001;

   /**
    * 网络错误
    */
   public static final int NETWORK_ERROR = 1002;

   /**
    * 协议错误
    */
   public static final int HTTP_ERROR = 1003;


   /**
    * 服务器异常 或 网络通道异常
    *
    * @param e
    * @return
    */
   public static ApiException handleException(Throwable e) {
       ApiException ex;
       if (e instanceof JsonParseException
               || e instanceof JSONException
               || e instanceof ParseException) {
           //解析错误
           ex = new ApiException(PARSE_ERROR, e.getMessage());
           return ex;
       } else if (e instanceof ConnectException) {
           //网络错误
           ex = new ApiException(NETWORK_ERROR, e.getMessage());
           return ex;
       } else if (e instanceof UnknownHostException || e instanceof SocketTimeoutException) {
           //连接错误
           ex = new ApiException(NETWORK_ERROR, e.getMessage());
           return ex;
       } else {
           //未知错误
           ex = new ApiException(UNKNOWN, e.getMessage());
           return ex;
       }
   }

  • 异常类base,通过code 和msg 放回对应的Throwble
public class ApiException extends Throwable {
    private int code;
    private String displayMessage;

    public ApiException(int code, String displayMessage) {
        this.code = code;
        this.displayMessage = displayMessage;
    }

    public ApiException(int code, String message, String displayMessage) {
        super(message);
        this.code = code;
        this.displayMessage = displayMessage;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getDisplayMessage() {
        return displayMessage;
    }

    public void setDisplayMessage(String displayMessage) {
        this.displayMessage = displayMessage;
    }

    @Override
    public String getMessage() {
        return displayMessage;
    }
}
  • 再来看看ResponseTransformer
    /**
     * 非服务器产生的异常,比如本地无无网络请求,Json数据解析错误等等。
     *
     * @param <T>
     */
  private static class ErrorResumeFunction<T> implements Function<Throwable, ObservableSource<? extends BaseResponse<T>>> {

        @Override
        public ObservableSource<? extends BaseResponse<T>> apply(Throwable throwable) throws Exception {
            return Observable.error(CustomException.handleException(throwable));
        }
    }

   /**
     * 服务其返回的数据解析
     * 正常服务器返回数据和服务器可能返回的exception
     *
     * @param <T>
     */
    private static class ResponseFunction<T> implements Function<BaseResponse<T>, ObservableSource<T>> {

        @Override
        public ObservableSource<T> apply(BaseResponse<T> response) throws Exception {
            try {
                if (null != response && response.getSuccess()) {
                    return Observable.just(response.getData() == null ? ((T) new Object()) : response.getData());
                } else if (null != response && 401 == response.getErrCode()) {
                    return Observable.error(new ApiException(-2, response == null ? "need login first!" : response.getErrMsg()));
                } else {
                    return Observable.error(new ApiException(-1, response == null ? "Network related errors" : response.getErrMsg()));
                }
            } catch (
                    Exception e) {
                Log.e("error", e.getMessage());
                return Observable.error(new ApiException(-1, "Exception related error"));
            }
        }
    }
    上面的errcode 可以根据业务需求返回对应的msg,不一定都是401.这里的401 是我项目中的业务code
 /**
     * 转换本地异常、服务器异常、和抛出正常数据
     *
     * @param <T>
     * @return
     */

    public static <T> ObservableTransformer<BaseResponse<T>, T> handleResult() {
        return upstream -> upstream
                .compose(RxScheduler.getInstance().schedulers())
                .onErrorResumeNext(new ErrorResumeFunction<>())
                .flatMap(new ResponseFunction<>()).observeOn(AndroidSchedulers.mainThread());
    }

通过compose 操作整个流 去分离出异常和正常数据,最后通过flatmap 将分离的数据转包。具体这两个操作符下一篇会详细介绍。

  • step4 线程调度器 RxScheduler
  @Override
    public Scheduler io() {
        return Schedulers.io();
    }

    @Override
    public Scheduler ui() {
        return AndroidSchedulers.mainThread();
    }

源码已上传github

end

猜你喜欢

转载自blog.csdn.net/Android_LeeJiaLun/article/details/108334356