網(wǎng)絡(luò)第三方框架有xutil、xutil3、volle以及okhttp 和okhttp衍生出來的一大批殼外的殼
那么既然已經(jīng)有了那么多優(yōu)秀的產(chǎn)品為什么還要自己封裝呢,有以下兩個原因:
1.引入retrofit、 noHttp 等增加了很多不必要的代碼,增大了apk 包(第三方引用的會被keep)
2.使用retrofit、 noHttp等會對程序的可擴展性產(chǎn)生重大隱患
3.適合自己項目的才是好方案,合理的中間層處理會大大降低程序的代碼量和開銷
下面將從代碼角度分析如何封裝適合自己的網(wǎng)絡(luò)框架
本文僅適合具備較強學習能力的開發(fā)者閱讀,因為此文的目的在于提供思路和簡單的使用場景,為達到適合自己的網(wǎng)絡(luò)框架需求需要自己對中間層根據(jù)范例進行處理,對合適的modle進行編寫。
在此之前你需要具備以下基礎(chǔ)技能點:
接口回調(diào)、泛型、線程
一、使用場景
獲取Person 對象,onSucess、onFaild回調(diào)在主線程
public void getPerson(){
HashMap<String ,String>params=new HashMap<String,String>();
params.put("type","1");
HttpRequest.postRequest(context, "http://test/person", params,
new ModleRequest<Person>(Person.class) {
@Override
protected void onSucess(Person person) {}
@Override
protected void onFaild(Exception e) { }
});
}
二、入口程序
import java.io.File;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import cnn.customer.utils.net.action.DownLoad;
import cnn.customer.utils.net.action.GetRequest;
import cnn.customer.utils.net.action.PostRequest;
import cnn.customer.utils.net.action.UploadRequest;
import cnn.customer.utils.net.inter.BaseRequest;
import cnn.customer.utils.net.inter.FileRequest;
import cnn.customer.utils.net.modle.StringRequest;
import okhttp3.OkHttpClient;
/**
* Created by biyunlong on 2016/9/5.
*/
public class HttpRequest {
public static OkHttpClient okHttpClient;
public static void init() {
if (null == okHttpClient) {
OkHttpClient.Builder ClientBuilder = new OkHttpClient.Builder();
ClientBuilder.readTimeout(60, TimeUnit.SECONDS);//讀取超時
ClientBuilder.connectTimeout(60, TimeUnit.SECONDS);//連接超時
ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//寫入超時
okHttpClient = ClientBuilder.build();
}
}
public static void getRequest(String url, final BaseRequest re) {
GetRequest.getRequest(url,re,okHttpClient);
}
//普通接口
public static void postRequest(HashMap<String, String> params, String url, final BaseRequest re) {
PostRequest.postRequest(params,url,re,okHttpClient);
}
//下載文件
public static void downLoad(String url, String path, String name, FileRequest fileRequest){
DownLoad.downLoadFile(url,path,name,okHttpClient,fileRequest);
}
//上傳單個圖片
public void uploadImage(String url, HashMap<String, String> params, File file, StringRequest stringRequest){
UploadRequest.upLoadFile(url,params,file,stringRequest,okHttpClient);
}
//上傳多張圖片
public void uploadMoreImage(String url, HashMap<String, String> params, HashMap<String, String> params2, File file, StringRequest stringRequest){
UploadRequest.uploadMoreFile(url,params,params2,stringRequest,okHttpClient);
}
//上傳base64圖片
public void UploadBase64( String url, HashMap<String, String> params, String content, final BaseRequest re){
UploadRequest.UploadBase64(url,params,content,re,okHttpClient);
}
}
三、執(zhí)行程序
import android.util.Log;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import cnn.customer.utils.net.inter.BaseRequest;
import cnn.customer.utils.net.tools.MainHandler;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* 文件描述:
* 創(chuàng) 建 人:byl
* 創(chuàng)建時間:2017/9/5 0005 18:13
*/
public class PostRequest {
public static void postRequest(HashMap<String, String> params, String url, final BaseRequest re, OkHttpClient okHttpClient) {
//創(chuàng)建Form表單對象,可以add多個鍵值隊
FormBody.Builder builder = new FormBody.Builder();
if (params != null) {
Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
builder.add(entry.getKey(), entry.getValue() + "");
}
}
FormBody formBody = builder.build();
//創(chuàng)建一個Request
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
//發(fā)送請求獲取響應(yīng)
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
re.baseOnFaild(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String str = response.body().string();
MainHandler.getInstance().post(new Runnable() {
@Override
public void run() {
re.baseOnSucess(str);
}
});
Log.d("debug", str);
}
});
}
}
四、modle中間層
可根據(jù)需要自行編寫StringRequest 或者ListRequest ,也可以根據(jù)泛型指定返回格式,然后通過類型轉(zhuǎn)換(不推薦)
/**
* Created by biyunlong on 2016/9/5.
*/
public abstract class BaseRequest {
public abstract void baseOnSucess(String json);
public abstract void baseOnFaild(Exception e);
}
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.ParameterizedType;
import cnn.customer.utils.net.inter.BaseRequest;
/**
* Created by biyunlong on 2017/5/3.
* Make progress every day
*/
public abstract class BeanRequest<T> extends BaseRequest {
private int status;
private String msg;
@Override
public void baseOnSucess(String jsonstr) {
try {
JSONObject jsonRoot = new JSONObject(jsonstr);
status=jsonRoot.getInt("result");
msg=jsonRoot.getString("message");
if(status==200){
JSONObject jsonResult=jsonRoot.getJSONObject("data");
String strResult=jsonResult.toString();
T t=(T)(new Gson().fromJson(strResult,((ParameterizedType)(getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
onSucess(t,status,msg);
}else{
onSucess(null,status,msg);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void baseOnFaild(Exception e) {
onFaild(e);
}
public abstract void onSucess(T t,int status,String msg);
public abstract void onFaild(Exception e);
}