前言:为什么需要自定义网络访问框架?
1.为了解耦
2.为了日后快速更换网络引擎
网络访问框架
一、使用样例
HttpUtils.with(context)//上下文
.url(url)//请求链接
.addParam("key", "value")//请求参数键值对
//.exchangeEngine(new 网络引擎接口规范 IHttpEngine 的实现类,如:new OkHttpEngine())//切换网络引擎
//.get()//默认是 get 请求,可省略
.execute(new HttpCallBack<T>() {//请求结果回调(泛型 T)
@Override
public void onError(Exception e) {
//失败回调
}
@Override
public void onSuccess(T data) {
//成功回调
}
});
二、核心类简介
Ⅰ、相关核心类
1.HttpUtils: 网络访问的工具类,可链式调用,发起网络请求
2.IHttpEngine: 网络引擎的规范,如:get()、post()等
3.OkHttpEngine: 具体的网络引擎,实现了 IHttpEngine
4.IEngineCallBack: 请求回调接口
5.HttpCallBack: 请求回调抽象类,实现了 IEngineCallBack,onSuccess(T t) 返回实体类 t
Ⅱ、UML 图
三、核心类
1.HttpUtils:
//网络引擎接口
private static IHttpEngine mHttpEngine = null;
public static Handler handler = new Handler();
//需要在 Application 中初始化网络引擎,参数为具体网络引擎
public static void initEngine(IHttpEngine httpEngine) {
mHttpEngine = httpEngine;
}
//切换网络引擎
public HttpUtils exchangeEngine(IHttpEngine httpEngine) {
mHttpEngine = httpEngine;
return this;
}
public static HttpUtils with(Context context) {
return new HttpUtils(context);
}
//设置请求的 url
public HttpUtils url(String url) {
this.mUrl = url;
return this;
}
//设置请求方式为 get 请求
public HttpUtils get() {
this.mType = GET_TYPE;
return this;
}
//添加请求参数
public HttpUtils addParam(String key, Object value) {
mParams.put(key, value);
return this;
}
//执行网络请求
public void execute(IEngineCallBack callBack) {
//判断执行方法,默认为 GET 请求
if (mType == GET_TYPE) {
get(mUrl, mParams, callBack);
} else if (mType == POST_TYPE) {
post(mUrl, mParams, callBack);
}
}
//get 请求
private void get(String url, Map<String, Object> params, IEngineCallBack callBack) {
//通过网络引擎接口执行 get 请求
mHttpEngine.get(mContext, url, params, callBack);
}
//post 请求
private void post(String url, Map<String, Object> params, IEngineCallBack callBack) {
//通过网络引擎接口执行 post 请求
mHttpEngine.post(mContext, url, params, callBack);
}
//拼接请求参数
public static String joinParams(String url, Map<String, Object> params) {
if (params == null || params.size() <= 0) {
return url;
}
StringBuffer sb = new StringBuffer(url);
if (!url.contains("?")) {
sb.append("?");
} else {
if (!url.endsWith("?")) {
sb.append("&");
}
}
for (Map.Entry<String, Object> entry : params.entrySet()) {
sb.append(entry.getKey() + "=" + entry.getValue() + "&");
}
sb.deleteCharAt(sb.length() - 1);//删除最后的 &
return sb.toString();
}
2.OkHttpEngine
private static OkHttpClient mOkHttpClient = new OkHttpClient();
@Override
public void get(Context context, String url, Map<String, Object> params, final IEngineCallBack callBack) {
final String joinUrl = HttpUtils.joinParams(url, params);
Request.Builder builder = new Request.Builder()
.url(joinUrl)
.tag(context);
//默认就是 GET 方法,可以省略
//builder.method("GET", null);
final Request request = builder.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callBack.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String resultJson = response.body().string();
//请求结果回调到主线程
HttpUtils.handler.post(new Runnable() {
@Override
public void run() {
callBack.onSuccess(resultJson);
}
});
}
});
}
@Override
public void post(Context context, String url, Map<String, Object> params, final IEngineCallBack callBack) {
RequestBody requestBody = appendBody(params);
final Request request = new Request.Builder()
.url(url)
.tag(context)
.post(requestBody)
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callBack.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
//请求结果回调到主线程
HttpUtils.handler.post(new Runnable() {
@Override
public void run() {
callBack.onSuccess(result);
}
});
}
});
private RequestBody appendBody(Map<String, Object> params) {
//处理字符串
FormBody.Builder builder = new FormBody.Builder();
for (Map.Entry<String, Object> mEntry : params.entrySet()) {
String mEntryKey = mEntry.getKey();
Object mEntryValue = mEntry.getValue();
if (TextUtils.isEmpty(mEntryKey)) {
continue;
}
builder.addEncoded(mEntryKey, mEntryValue.toString());
}
return builder.build();
}
3.HttpCallBack
@Override
public void onSuccess(String result) {
Gson gson = new Gson();
try {
//获取当前类的泛型类型
T jsonResult = (T) gson.fromJson(result, HttpUtils.getClazzInfo(this));
//回调自己的 onSuccess(T result)
onSuccess(jsonResult);
} catch (JsonSyntaxException e) {//json 转换失败: result 是一个畸形的 json 元素, 此时就直接使用返回的字符串即可
e.printStackTrace();
}
}
//实体类的成功回调
public abstract void onSuccess(T result);