在开发过程中有时候一个项目可能会用两三个网络请求框架,怎么搞才能切换自如呢,答案就是自己搞一套规范来封装三方库。
多余的话就不说了,直接看代码。
网络请求规范(只写了get和post请求,下载和上传你可以自己实现):
public interface IHttpEngine {
/**
* get请求
*
* @param context
* @param url
* @param params
* @param callback
*/
void get(Context context, String url, Map<String, Object> params, EngineCallback callback);
/**
* post请求
*
* @param context
* @param url
* @param params
* @param callback
*/
void post(Context context, String url, Map<String, Object> params, EngineCallback callback);
}
然后封装OKHttp实现该接口,当然你也可以使用别的三方库来实现在接口:
public class OkHttpEngine implements IHttpEngine {
private static OkHttpClient sOkHttpClient = new OkHttpClient();
private static Handler sHandler = new Handler();
@Override
public void get(Context context, String url,
Map<String, Object> params,
final EngineCallback callback) {
final String jointUrl = HttpUtils.jointParams(url, params);
Log.v("OkHttpEngine->Get", jointUrl);
Request request = new Request.Builder()
.url(jointUrl)
.tag(context)
.build();
sOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
sHandler.post(new Runnable() {
@Override
public void run() {
callback.onError(e);
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.v("OkHttpEngine->Get", "result: " + result);
sHandler.post(new Runnable() {
@Override
public void run() {
callback.onSuccess(result);
}
});
}
});
}
@Override
public void post(Context context, String url,
Map<String, Object> params,
final EngineCallback callback) {
final String jointUrl = HttpUtils.jointParams(url, params);
Log.v("OkHttpEngine->Post", jointUrl);
RequestBody requestBody = appendBode(params);
Request request = new Request.Builder()
.url(url)
.tag(context)
.post(requestBody)
.build();
sOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
sHandler.post(new Runnable() {
@Override
public void run() {
callback.onError(e);
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.v("OkHttpEngine->Post", "result: " + result);
sHandler.post(new Runnable() {
@Override
public void run() {
callback.onSuccess(result);
}
});
}
});
}
/**
* 组装post请求参数
*
* @param params
* @return
*/
private RequestBody appendBode(Map<String, Object> params) {
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
addParams(builder, params);
return builder.build();
}
/**
* 添加参数
*
* @param builder
* @param params
*/
private void addParams(MultipartBody.Builder builder, Map<String, Object> params) {
if (params != null && !params.isEmpty()) {
for (String key : params.keySet()) {
builder.addFormDataPart(key, params.get(key) + "");
Object value = params.get(key);
if (value instanceof File) {
//处理文件 -->Object File
File file = (File) value;
builder.addFormDataPart(key, file.getName(), RequestBody.Companion
.create(file, MediaType.Companion.parse(guessMimeType(file.getAbsolutePath()))));
} else if (value instanceof List) {
//代表提交的是List集合
try {
List<File> listFiles = (List<File>) value;
for (int i = 0; i < listFiles.size(); i++) {
//获取文件
File file = listFiles.get(i);
builder.addFormDataPart(key + i, file.getName(), RequestBody.Companion
.create(file, MediaType.Companion.parse(guessMimeType(file.getAbsolutePath()))));
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
builder.addFormDataPart(key, value + "");
}
}
}
}
/**
* 猜测文件类型
*
* @param path
* @return
*/
private String guessMimeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null) {
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}
}
最后是调用的工具类:
public class HttpUtils {
private String mUrl;
//请求方式
private int mType = GET_TYPE;
private static final int POST_TYPE = 0x0011;
private static final int GET_TYPE = 0x0012;
//默认引擎
private static IHttpEngine mHttpEngine;
private Map<String, Object> mParams;
private Context mContext;
private HttpUtils(Context context) {
this.mContext = context;
mParams = new HashMap<>();
}
//在Application中初始化引擎
public static void initHttpEngine(IHttpEngine httpEngine) {
mHttpEngine = httpEngine;
}
public static HttpUtils with(Context context) {
return new HttpUtils(context);
}
//设置url
public HttpUtils url(String url) {
this.mUrl = url;
return this;
}
//设置请求方式
public HttpUtils post() {
mType = POST_TYPE;
return this;
}
public HttpUtils get() {
mType = GET_TYPE;
return this;
}
//添加参数
public HttpUtils addParam(String key, Object value) {
mParams.put(key, value);
return this;
}
public HttpUtils addParams(Map<String, Object> params) {
mParams.putAll(params);
return this;
}
//添加回调
public void execute(EngineCallback callback) {
if (callback == null) {
callback = EngineCallback.DEFAULT_CALL_BACK;
}
onPrepare();
callback.onPreExecute(mContext, mParams);
//判断执行方法
if (mType == POST_TYPE) {
mHttpEngine.post(mContext, mUrl, mParams, callback);
} else if (mType == GET_TYPE) {
mHttpEngine.get(mContext, mUrl, mParams, callback);
}
}
public void execute() {
execute(null);
}
/**
* 每次切换网络请求引擎
*
* @param httpEngine
*/
public HttpUtils exchangeEngine(IHttpEngine httpEngine) {
mHttpEngine = httpEngine;
return this;
}
/**
* 初始化加入一些参数和网络引擎
*/
private void onPrepare() {
if (TextUtils.isEmpty(mUrl)) {
throw new NullPointerException("url 为 null!");
}
if (this.mHttpEngine == null) {
throw new NullPointerException("第三方的引擎为空,请在Application中初始化!");
}
}
public static String jointParams(String url, Map<String, Object> params) {
if (params == null || params.size() <= 0) {
return url;
}
StringBuffer stringBuffer = new StringBuffer(url);
if (!url.contains("?")) {
stringBuffer.append("?");
} else {
if (!url.endsWith("?")) {
stringBuffer.append("&");
}
}
for (Map.Entry<String, Object> entry : params.entrySet()) {
stringBuffer.append(entry.getKey() + "=" + entry.getValue() + "&");
}
stringBuffer.deleteCharAt(stringBuffer.length() - 1);
return stringBuffer.toString();
}
/**
* 解析上一个类上面的class信息
* 获得泛型类的真实类型
*/
public static Class<?> analysisClassInfo(Object object) {
Type genType = object.getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
return (Class<?>) params[0];
}
}
这就完事了。
代码很简单,希望自己能走的更远