Retrofit & RxJava 封装篇
2018-09-13 本文已影响0人
kjy_112233
一、封装RxJava
(1)BaseResponse封装请求返回数据
public class BaseResponse<T> {
private int res_code;
private String err_msg;
private T demo;
//code...
}
(2)BaseObserver封装返回数据处理
public abstract class BaseObserver<T> implements Observer<BaseResponse<T>> {
private static final String TAG = "BaseObserver";
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull BaseResponse<T> tBaseResponse) {
if (tBaseResponse.getRes_code() == 200) {
onSuccess(tBaseResponse.getDemo());
} else {
onFailure(null, tBaseResponse.getErr_msg());
}
}
@Override
public void onError(@NonNull Throwable e) {
try {
if (e instanceof SocketTimeoutException) {//请求超时
onFault(e, "请求超时,请稍后再试");
} else if (e instanceof ConnectException) {//网络连接超时
onFault(e, "网络连接超时,请检查网络状态");
} else if (e instanceof SSLHandshakeException) {//安全证书异常
onFault(e, "安全证书异常");
} else if (e instanceof HttpException) {//请求的地址不存在
int code = ((HttpException) e).code();
if (code == 504) {
onFault(e, "网络异常,请检查您的网络状态");
} else if (code == 404) {
onFault(e, "请求的地址不存在");
} else {
onFault(e, "请求失败");
}
} else if (e instanceof UnknownHostException) {//域名解析失败
onFault(e, "域名解析失败");
} else {
onFault(e, "error:" + e.getMessage());
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
@Override
public void onComplete() {
}
public abstract void onSuccess(T demo);
public abstract void onFailure(Throwable e, String errorMsg);
public abstract void onFault(Throwable e, String errorMsg);
}
(3)DialogObserver封装网络请求加载提示
public abstract class DialogObserver<T> extends BaseObserver<T> {
private boolean mShowDialog;
private ProgressDialog dialog;
private Context mContext;
private Disposable d;
private DialogObserver(Context context, Boolean showDialog) {
mContext = context;
mShowDialog = showDialog;
}
public DialogObserver(Context context) {
this(context, true);
}
@Override
public void onSubscribe(@NonNull Disposable d) {
this.d = d;
if (!isConnected(mContext)) {
Toast.makeText(mContext, "未连接网络", Toast.LENGTH_SHORT).show();
if (d.isDisposed()) {
d.dispose();
}
} else {
if (dialog == null && mShowDialog) {
dialog = new ProgressDialog(mContext);
dialog.setMessage("正在加载中");
dialog.show();
}
}
}
@Override
public void onError(@NonNull Throwable e) {
if (d.isDisposed()) {
d.dispose();
}
hidDialog();
super.onError(e);
}
@Override
public void onComplete() {
if (d.isDisposed()) {
d.dispose();
}
hidDialog();
super.onComplete();
}
private void hidDialog() {
if (dialog != null && mShowDialog)
dialog.dismiss();
dialog = null;
}
/**
* 是否有网络连接,不管是wifi还是数据流量
*/
private static boolean isConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null) {
return false;
}
return info.isAvailable();
}
}
二、封装Retrofit
(1)NetworkInterface封装网络请求接口
public interface NetworkInterface {
String HOST = "http://服务器地址.com/";
@GET()
Observable<BaseResponse<String>> getBody(@Url String url);
@POST()
Observable<BaseResponse<RegisterLogin>> registerLogin(@Url String url, @Body RequestBody body);
}
(2)RetrofitUtils封装拦截器
public class RetrofitUtils {
private static final int DEFAULT_TIMEOUT = 10;//超时时间
private static volatile NetworkInterface networkInterface = null;
/**
* 创建网络请求接口实例
*/
public static NetworkInterface getRequestInterface() {
if (networkInterface == null) {
synchronized (NetworkInterface.class) {
networkInterface = provideRetrofit().create(NetworkInterface.class);
}
}
return networkInterface;
}
/**
* 初始化必要对象和参数
*/
private static Retrofit provideRetrofit() {
File cacheFile = new File(CPApplication.getContext().getCacheDir(), "cache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache) //设置缓存
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.addNetworkInterceptor(getRequestHeader())
.addInterceptor(getHttpLoggingInterceptor())
.addInterceptor(commonParamsInterceptor())
.addInterceptor(getResponseHeader())
.addInterceptor(getCacheInterceptor())
.build();
//设置网络请求的Url地址
//设置数据解析器
//支持RxJava平台
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(NetworkInterface.HOST)//设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create())//设置数据解析器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持RxJava平台
.client(client)
.build();
return retrofit;
}
/**
* 日志拦截器
*/
private static HttpLoggingInterceptor getHttpLoggingInterceptor() {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtils.Le("OkHttp", "log = " + message);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return loggingInterceptor;
}
/**
* 请求头拦截器
*/
private static Interceptor getRequestHeader() {
Interceptor headerInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder();
//使用addHeader()不会覆盖之前设置的header,若使用header()则会覆盖之前的header
builder.addHeader("Accept", "application/json");
builder.addHeader("Content-Type", "application/json; charset=utf-8");
builder.addHeader("token", "d08986536b5e3678119aac9b892439a8");
builder.removeHeader("User-Agent");
builder.method(originalRequest.method(), originalRequest.body());
Request.Builder requestBuilder = builder.method(originalRequest.method(), originalRequest.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
};
return headerInterceptor;
}
/**
* 统一的请求参数拦截器
*/
private static Interceptor commonParamsInterceptor() {
Interceptor commonParams = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request originRequest = chain.request();
Request request;
HttpUrl httpUrl = originRequest.url().newBuilder().
addQueryParameter("paltform", "android").
addQueryParameter("version", "1.0.0").build();
request = originRequest.newBuilder().url(httpUrl).build();
return chain.proceed(request);
}
};
return commonParams;
}
/**
* 通过响应拦截器实现了从响应中获取服务器返回的time
*/
private static Interceptor getResponseHeader() {
Interceptor interceptor = new Interceptor() {
@NonNull
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Response response = chain.proceed(chain.request());
String timestamp = response.header("time");
if (timestamp != null) {
//获取到响应header中的time
}
return response;
}
};
return interceptor;
}
/**
* 在无网络的情况下读取缓存,有网络的情况下根据缓存的过期时间重新请求
*/
private static Interceptor getCacheInterceptor() {
Interceptor commonParams = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetworkUtils.isConnected()) {
//无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。
request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE)
.build();
}
okhttp3.Response response = chain.proceed(request);
if (NetworkUtils.isConnected()) {//有网络情况下,根据请求接口的设置,配置缓存。
//这样在下次请求时,根据缓存决定是否真正发出请求。
String cacheControl = request.cacheControl().toString();
//当然如果你想在有网络的情况下都直接走网络,那么只需要
//将其超时时间这是为0即可:String cacheControl="Cache-Control:public,max-age=0"
int maxAge = 60 * 60; // read from cache for 1 minute
return response.newBuilder()
// .header("Cache-Control", cacheControl)
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
} else {
//无网络
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return response.newBuilder()
.header("Cache-Control", "public,only-if-cached,max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
}
};
return commonParams;
}
}
三、实际用例
(1)封装网络请求参数
public class HttpService {
public static Observable<BaseResponse<RegisterLogin>> registerLogin(String phone, String code) {
Gson gson = new Gson();
Map<String, String> map = new HashMap<String, String>();
map.put("phone", phone);
map.put("code", code);
String strJson = gson.toJson(map);
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), strJson);
return RetrofitUtils.getRequestInterface()
.registerLogin("", body)
.observeOn(AndroidSchedulers.mainThread())//回调在主线程
.subscribeOn(Schedulers.io());
}
}
(2)调用网络请求
HttpService.registerLogin("", "")
.subscribe(new BaseObserver<RegisterLogin>() {
@Override
public void onSuccess(RegisterLogin demo) {
}
@Override
public void onFailure(Throwable e, String errorMsg) {
}
@Override
public void onFault(Throwable e, String errorMsg) {
}
});//执行在io线程