我来了我来了,今天手把手教你二次封装网络框架
首先为什么需要二次封装网络框架?
情景一
领导说,小明咱们需要有个网络框架,你去调研一下,然后接入到咱们项目,小明赶紧去找,发现目前okhttp最好,而且有好多封装好的比如okgo,然后就把怎么用的记录下来了
OkGo.<String>post(HttpUrls.APPHOMEAPI)
.tag(this)
.cacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)
.converter(new StringConvert())
.adapt(new ObservableResponse<String>())
.subscribeOn(Schedulers.io())
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
showLoadingDialog();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Response<String>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
addDisposable(d);
}
@Override
public void onNext(@NonNull Response<String> response) {
dealNetData(response.body());
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
ToastUtils.showShort(RMHttpConstant.ERROR_MSG);
dismissLoadingDialog();
}
@Override
public void onComplete() {
dismissLoadingDialog();
}
});
正好 A同事过来了,说这个怎么添加请求头啊,小明记下了说一会告诉你,B同事过来了,说我不会用rxJava怎么办呢,小名记下了说一会告诉你,.....一共来了一万个同事。小明卒。
原因一:简单好用,傻瓜式的操作。
情景二
一万个页面代码刚刚写完,领导说retrofit不错,小明你调研一下,然后替换一下,小明卒。
原因二:维护性(更换网络框架的成本低,最好一行代码实现替换网络框架)
开始实践。
第一步 功能放在接口中,最核心的东西全在这个接口可以一目了然,按照这个约束进行编程。
public interface XHttp {
/**
* post网络请求
* @param url
* @param tag
* @param params
* @return
*/
void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack);
void doGet(String url, Object tag, HashMap<String, String> params,IHttpCallBack iokGoCallBack);
void cancel(Object tag);
}
第二步 实现接口功能
1,实现接口功能。
public class OKGoHttpImp implements XHttp {
private HashMap<Object,CompositeDisposable> mDisposables=new HashMap<>();
@Override
public void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
PostRequest<String> request = OkGo.<String>post(url).tag(tag).headers(OkGoUtil.getHeaders()).params(params, true).converter(new StringConvert());
request.adapt(new ObservableBody<String>()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
add(tag,d);
}
@Override
public void onNext(String s) {
iokGoCallBack.onSuccess(s);
}
@Override
public void onError(Throwable e) {
iokGoCallBack.onFail(e);
}
@Override
public void onComplete() {
}
});
}
@Override
public void doGet(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
GetRequest<String> request = OkGo.<String>get(url).tag(tag).headers(OkGoUtil.getHeaders()).params(params, true).converter(new StringConvert());
request.adapt(new ObservableBody<String>()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
add(tag,d);
}
@Override
public void onNext(String s) {
iokGoCallBack.onSuccess(s);
}
@Override
public void onError(Throwable e) {
iokGoCallBack.onFail(e);
}
@Override
public void onComplete() {
}
});
}
private void add(Object tag, Disposable d){
CompositeDisposable disposables = mDisposables.get(tag);
if (disposables==null){
disposables=new CompositeDisposable();
mDisposables.put(tag,disposables);
}
disposables.add(d);
}
public void cancel(Object tag) {
OkGo.getInstance().cancelTag(tag);
CompositeDisposable disposables = mDisposables.get(tag);
if (disposables!=null){
disposables.clear();
}
}
情景三
领导说okgo不行,咱们试试别的网络框架。
看上去也没什么问题,而且修改网络框架只需要在这里一次修改就全局替换了。
小明改完之后,领导说不行,我觉得还是okgo比较好再替换回去吧。
小明一顿粘贴复制改来改去,如此反复一万次,小明卒。
接下来代理登场,实现接口,持有的一个接口的实现类,通过初始化传入,看代码
public final class XHttpClient implements XHttp {
private static XHttp mRealHttp;
@Override
public void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
mRealHttp.doPost(url,tag,params,iokGoCallBack);
}
@Override
public void doGet(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
mRealHttp.doGet(url,tag,params,iokGoCallBack);
}
@Override
public void cancel(Object tag) {
mRealHttp.cancel(tag);
}
private static class Holder {
private static final XHttpClient INSTANCE = new XHttpClient();
}
private XHttpClient() {
}
public static void init(XHttp http) {
mRealHttp=http;
}
public static final XHttpClient get() {
return Holder.INSTANCE;
}
}
第三步 对外使用
XHttpClient.init(new OKGoHttpImp());//初始化网络框架
// XHttpClient.init(new RetrofitImp());//初始化网络框架
//XHttpClient.init(new OKUtlisImp());//初始化网络框架
.....
XHttpClient.get().doPost(url, this, params,iHttpCallBack);//外部调用
这里可能有人会说,我多创建几个类实现接口,跟你这个不就一样了吗,也支持多个功能来回切换了?
替换网络框架还是需要全局都修改,而通过代理则可以实现一行代码替换框架
优点:框架功能一目了然,直接看接口功能; 一行代码替换底层网络框架。
最后来张图

数据解析类
public interface IHttpCallBack {
void onSuccess(String result);
void onFail(Throwable error);
}
public abstract class XHttpCallBack<result> implements IHttpCallBack {
@Override
public void onSuccess(String result) {
int code = XJsonParseUtils.getInt(result, "code");
if (code==0){
Type type = TUtils.getTTypeInfo(this, 0);
result resultBody = XJsonParseUtils.json2Obj(result, type);
onSuccess(resultBody);
}else {
String msg = XJsonParseUtils.getString(result, "msg");
ApiException apiException = new ApiException(code, msg);
XErrorUtils.processException(apiException);
onFail(apiException);
}
//这里需要处理
}
@Override
public void onFail(Throwable error) {
XErrorUtils.processException(error);
onError(error);
}
public abstract void onSuccess(result result);
public void onError(Throwable error) {
}
}
public final class TUtils {
/**
* @param object 当前 类的实例对象
* @param index 要获取的泛型的下标
* @param <T>
* @return
*/
public static <T> T get(Object object, int index) {
T t = null;
try {
return t = (T) getTClassInfo(object, index).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return t;
}
/**
* 获取泛型的类型
*
* @param clazz 泛型类的当前对象
* @param index 泛型的下标
* @return
*/
public static Class<?> getTClassInfo(Class<?> clazz, int index) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
return Object.class;
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
public static Class<?> getTClassInfo(Object object, int index) {
return getTClassInfo(object.getClass(), index);
}
/**
* 获取当前类上泛型 的type 可以用来解析
* @param object
* @param index
* @return
*/
public static Type getTTypeInfo(Object object, int index){
Type genType = object.getClass().getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return null;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
return params[index];
}
}
网友评论