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}"
]
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 开始搭建
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);
}
}
数据entity base, 客户端服务器约定 errMsg、 errCode
public class BaseResponse<T> implements Serializable {
private boolean success;
private String errMsg;
private int errCode;
private T data;
}
分离器的作用是将正常数据和异常分离出来各种处理
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;
}
}
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;
}
}
/**
* 非服务器产生的异常,比如本地无无网络请求,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 将分离的数据转包。具体这两个操作符下一篇会详细介绍。
@Override
public Scheduler io() {
return Schedulers.io();
}
@Override
public Scheduler ui() {
return AndroidSchedulers.mainThread();
}