說起訪問網絡,很天然的會用到okHttp,雖然okhttp已經封裝的比較完善, 調用也比較方便,但對於向我這樣比較懶的人,okhttp的調用仍是略顯複雜, 每次都要寫一樣重複的代碼,簡直不能忍受,那就封裝如下一句話調用完畢,豈不快哉。。。 廢話很少說,請抓穩扶好,老司機,走起。。。
重要的事情提一提:看不懂的文章最後有完整代碼,看看完整版應該就沒問題了。java
沒有什麼是一張圖說不清的,走起
網絡訪問框架通常都須要單例模式(singleton),首先咱們也進行單利模式。 1 首先私有化構造器,讓別人不能new出其它實例。 2 聲明該類的一個靜態成員變量實例,本篇爲instance 3 聲明一個公有的方法getInstance提供給調用者本類實例。 /** * 網絡訪問要求singleton */ private static OkHttpUtils instance; // 必需要用的okhttpclient實例,在構造器中實例化保證單一實例 private OkHttpClient mOkHttpClient; private OkHttpUtils() { /** * okHttp3中超時方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } 上面代碼在構造器中實例化出了okHttpClient的實例,既然咱們這個幫助類是單例的,那麼構造器中的okHttpClient也只會走一次,一定也是單實例的。
既然是工具類,確定要更加簡單,此處咱們須要提供針對GET和POST兩種方式的訪問方法。
/** * 對外提供的Get方法訪問 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 經過url和GET方式構建Request */ Request request = bulidRequestForGet(url); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); }
/** * 對外提供的Post方法訪問 * @param url * @param parms: 提交內容爲表單數據 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); }
/** * 對外提供的Post方法訪問 * @param url * @param json: 提交內容爲json數據 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); }
從這兩個方法,咱們能看到咱們須要構建GET和POST訪問方式對應的Request對象和咱們自定義的MycallBack接口,下面先來看一下構建Request對象。json
爲了你們更好的理解封裝流程,首先請你們回顧一下okhttp的使用流程: mOkHttpClient.newCall(request).enqueue(new Callback() {})
1.首先咱們來看構建GET須要的Request對象,這個也是最簡單的。markdown
/** * GET方式構建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); }
2.構建提交表單數據的Request對象網絡
/** * POST方式構建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); }
3.構建提交json數據的Request對象app
/** * POST方式構建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); }
上述代碼及分析基本上把簡單封裝的東西講完了,有了okhttpclient和request對象咱們須要處理聯網邏輯了,也就是上述的 requestNetWork方法。 private void requestNetWork(Request request, MyCallBack callBack) { /** * 處理連網邏輯,此處只處理異步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { callBack.onFailure(request, e); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { callBack.onSuccess(response); } else { callBack.onError(response); } } }); }
看到此處,估計有人會一臉懵逼,這個MyCallBack是個什麼鬼。 其實這是我定義的一個接口,那麼爲何要定義她呢。由於咱們在使用咱們的工具類的時候,訪問網絡成功後確定會有數據返回,咱們怎麼處理呢,okhttp內部經過一個callBack把數據回調回來,那麼咱們本身封裝的工具類不妨仿照他的作法 定義一個接口回調Response的內容。貼一下接口的內容 interface MyCallBack { void onLoadingBefore(Request request); void onSuccess(Response response); void onFailure(Request request, Exception e); void onError(Response response);
}框架
看到此處,以爲封裝已經完結了,不不不,還有一個重要的問題,不處理的話會致使崩潰的,這個問題就是,咱們定義接口回調的地方是在子線程,而咱們的Response很明顯須要拿回到主線程進行UI的更新,因此訪問網絡的方法requestNetWork須要經過Handler把子線程的Resonse發送到主線程,請看詳細實現。
private void requestNetWork(Request request, MyCallBack callBack) {異步
/** * 處理連網邏輯,此處只處理異步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { mHandler.post(() -> callBack.onSuccess(response)); } else { mHandler.post(() -> callBack.onError(response)); } } }); }
此工具類尚未完善,下篇文章繼續完善,待完善內容:返回Resonpse直接解析成javaBean返回。
public class OkHttpUtils { /** * 網絡訪問要求singleton */ private static OkHttpUtils instance; // 必需要用的okhttpclient實例,在構造器中實例化保證單一實例 private OkHttpClient mOkHttpClient; public static final MediaType JSON = MediaType. parse("application/json; charset=utf-8"); private Handler mHandler; private OkHttpUtils() { /** * okHttp3中超時方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); mHandler = new Handler(Looper.getMainLooper()); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } /** * 對外提供的Get方法訪問 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 經過url和GET方式構建Request */ Request request = bulidRequestForGet(url); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param parms: 提交內容爲表單數據 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param json: 提交內容爲json數據 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * POST方式構建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); } /** * POST方式構建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); } /** * GET方式構建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); } private void requestNetWork(Request request, MyCallBack callBack) { /** * 處理連網邏輯,此處只處理異步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { mHandler.post(() -> callBack.onSuccess(response)); } else { mHandler.post(() -> callBack.onError(response)); } } }); } }
定義的接口的完整代碼ide
interface MyCallBack {
void onLoadingBefore(Request request); void onSuccess(Response response); void onFailure(Request request, Exception e); void onError(Response response); }