站在世界的巔峯看世界的心情,決不是一個普通人可以體會的到的感受java
/** * Created by androidlongs on 16/9/12. * 站在頂峯,看世界 * 落在谷底,思人生 */ /** * 建立方式一: * * 當在JVM在加載單例類的時候,單例對象就會被創建 * 當其中有其餘的靜態方法的時候,使用類調用方法,沒有使用到該單例對象,可是單例對象也會被建立出來,從而形成了資源的浪費 */ public class Singleton { //直接建立 public static Singleton sSingleton = new Singleton(); //私有構造函數 private Singleton(){ } //返回對象體 public static Singleton getInstance(){ return sSingleton; } //獲取String的方法 public static String getString(){ return "single"; } }
/** * Created by androidlongs on 16/9/12. * 站在頂峯,看世界 * 落在谷底,思人生 */ /** * 建立方式二 * * 有點性能上的損失 */ class SingletonLazy{ //聲明變量 public static SingletonLazy sSingletonLazy; //私有構造函數 private SingletonLazy(){ } //提供對外方法 public static SingletonLazy getInstance(){ if (sSingletonLazy == null) { synchronized (SingletonLazy.class){ if (sSingletonLazy == null) { sSingletonLazy = new SingletonLazy(); } } } return sSingletonLazy; } //獲取String的方法 public static String getString(){ return "single"; } }
/** * 建立方式三 */ class CommonSingleton{ //私有構造 private CommonSingleton(){ } //提供對外方法 public static CommonSingleton getInstance(){ return SingletonHolder.commonSingleton; } //內部類方法維護 private static class SingletonHolder{ private static CommonSingleton commonSingleton = new CommonSingleton(); } //獲取String的方法 public static String getString(){ return "single"; } }
分析 簡述:android
1-一、能夠看到上面三種建立單例的方法,第一種方式被傳統命名爲餓漢式,單例對象隨着類的加載而被建立,當咱們使用類中的其餘靜態方法而沒有使用到單例對象的時候,單例對象依然會被建立出來,從某種角度來講,形成了必定的內存浪費。json
1-二、第二種方式被傳統命名爲懶漢式,也就是在調用實例化對象的時候,纔會將單例對象建立出來,當咱們使用類中的其餘靜態方法的時候,會同時有單例對象的null引用生成,在必定程度上會很消耗內存,再者建立實例化對象的時候,雙重非空鎖判斷,也是至關消耗性能的工做。設計模式
1-三、第三種方式能夠稱爲是完美設計版了,由於它能夠解決前兩種設計方法的不足之處,當去調用類的實例化方法的時候,單例對象纔會被建立,而當調用類中的其餘靜態方法的時候,對靜態單例對象沒有任何的操做,因此能夠說是比較完美的了,之因此能夠稱爲比較而不是徹底,是因使用這種方式建立,在進行序列化與反序列化的時候,會出現非單例對象問題。緩存
/** * Created by androidlongs on 16/9/12. * 站在頂峯,看世界 * 落在谷底,思人生 */ public class CommonOkhttpUtils { //私有化構造 private CommonOkhttpUtils(){ //初始化Okhttp配製 initOkHttpFunction(); } //提供實例化對象 public static CommonOkhttpUtils getUtilsInstance(){ return OkHttpSingle.sCommonOkhttpUtils; } //實例靜態內部類 private static class OkHttpSingle{ private static CommonOkhttpUtils sCommonOkhttpUtils = new CommonOkhttpUtils(); } //初始化Okhttp配製 private void initOkHttpFunction() { } }
固然在使用Okhttp3的時候 要先關聯依賴markdown
compile 'com.squareup.okhttp3:okhttp:3.3.1'
private OkHttpClient mOkHttpClient; //初始化Okhttp配製 private void initOkHttpFunction() { //配製網絡數據緩存 File cacheDirectory = APPApplication.getmContext().getExternalCacheDir(); //配製網絡數據緩存大小 10M int cacheSize = 10*1024*1024; // Cache cache = new Cache(cacheDirectory,cacheSize); //建立HttpClientBuilder OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); //設置緩存 以及超時間 以及獲取OkHttpClient對象 mOkHttpClient = builder.writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .cache(cache) .build(); }
其實建立一個網絡鏈接並無多複雜網絡
4-1 建立請求Request對象 app
4-2建立封裝參數的RequestBody對象(GET方法除外)框架
4-3 封裝請求參數 異步
4-4 建立請求Response對象實例
4-5 發起網絡請求
4-6 處理回調監聽
4-7 處理取消網絡請求標籤
/** * 異步GET網絡請求 * * @param url 請求網絡連接 * @param headerMap 請求網絡添加頭信息 * @param paramsMap 請求網絡參數 * @param cacheControl 緩存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 響應回調 * @param tag 網絡任務標識 */ public void okHttpGetRequest(String url, Map<String, String> headerMap, Map<String, String> paramsMap, CacheControl cacheControl, Callback callback, String tag) { //GET請求-1 封裝請求參數 //Get請求傳參數其實是在請求連接中攜帶參數 StringBuilder sb = new StringBuilder(); sb.append(url).append("?"); if (paramsMap != null && !paramsMap.isEmpty()) { for (String key : paramsMap.keySet()) { sb.append(key).append("=").append(paramsMap.get(key)).append("&"); } sb = sb.deleteCharAt(sb.length() - 1); url = sb.toString(); } //GET請求-2 獲取Builder Request.Builder builder = new Request.Builder().url(url); //GET請求-3 設置緩存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //GET請求-4添加請求頭信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //GET請求-5 建立請求Request對象 Request request = builder.build(); //GET請求-6 設置取消標籤 Call call = mOkHttpClient.newCall(request); //將請求標籤添加到請求Key集合中 mCallHashMap.put(tag, call); //GET請求-5 發起網絡請求 call.enqueue(callback); } /** * 移除 取消網絡任務 * * @param tag */ public void removeRequest(String tag) { //獲取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //若是包含KEY if (keyEntries.contains(tag)) { //獲取對應的Call Call call = mCallHashMap.get(tag); //若是沒有被取消 執行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除對應的KEY mCallHashMap.remove(tag); } }
這是GET請求參數最多的方法,咱們能夠在此基礎上封裝少參數的方法,例如不須要設置請求頭,請求參數,不指定緩存模式,對應的傳入null就能夠。這裏實際上就是將傳入的參數以KEY - VALUE的方式拼接在了請求連接中
對於網絡請求模式,默認有兩種,一是強制使用網絡請求數據 ,一是強制使用緩存,通常使用默認使用網絡請求就能夠
使用案例 :
//GET訪問 private void getRequestFunction() { //請求連接 String url = ""; //網絡請求標識 String tag = "getRequest"; //提交參數 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); //添加請求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okHttpGetRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //請求失敗回調方法 } @Override public void onResponse(Call call, Response response) throws IOException { //請求成功回調方法 } }, tag); } //取消網絡請求 private void canlaneRequest(String tag){ CommonOkhttpUtils.getUtilsInstance().removeRequest(tag); }
經過抓包能夠看到咱們提交的請求數據爲
/** * 異步POST網絡請求 提交表單數據 * * @param url 請求網絡連接 * @param headerMap 請求網絡添加頭信息 * @param parmMap 請求網絡參數 * @param cacheControl 緩存模式 * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 響應回調 * @param tag 網絡任務標識 */ public void okPostFormRequest(String url, Map<String, String> headerMap, Map<String, String> parmMap, CacheControl cacheControl, Callback callback, String tag) { //POST - FORM 表單 獲取請求參數BODY FormBody.Builder formBuilder = new FormBody.Builder(); //POST - FORM 表單 封裝參數 if (parmMap != null && !parmMap.isEmpty()) { for (Map.Entry<String, String> entry : parmMap.entrySet()) { formBuilder.add(entry.getKey(), entry.getValue()); } } //POST - FORM 獲取表單BODY RequestBody formBody = formBuilder.build(); //POST - FORM 構建請求Request Builder Request.Builder requestBuilder = new Request.Builder().url(url); //POST - FORM 設置緩存 if (cacheControl != null) { requestBuilder.cacheControl(cacheControl); } //POST - FORM 添加請求頭信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { requestBuilder.addHeader(entry.getKey(), entry.getValue()); } } //POST - FORM 構建請求Request Request request = requestBuilder.post(formBody).build(); //POST - FORM 構建請求響應Call Call call = mOkHttpClient.newCall(request); //POST - FORM 設置取消任務標籤 mCallHashMap.put(tag,call); //POST - FORM 發起請求 call.enqueue(callback); } /** * 移除 取消網絡任務 * * @param tag */ public void removeRequest(String tag) { //獲取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //若是包含KEY if (keyEntries.contains(tag)) { //獲取對應的Call Call call = mCallHashMap.get(tag); //若是沒有被取消 執行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除對應的KEY mCallHashMap.remove(tag); } } }
案例:
private void postRequestForm() { //請求連接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //網絡請求標識 String tag = "getRequest"; //提交參數 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); //添加請求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostFormRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //請求失敗回調方法 } @Override public void onResponse(Call call, Response response) throws IOException { //請求成功回調方法 } }, tag); }
經過抓包工具能夠看到提交的數據爲:
提交數據的格式爲: Content - Type:application/x-www-form-urlencoded
添加的請求頭爲 verson : 11
提交的參數爲:
/** * 異步POST網絡請求 提交JSON數據 * * @param url 請求網絡連接 * @param headerMap 請求網絡添加頭信息 * @param parmMap 請求網絡參數 * @param cacheControl 緩存模式 * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 響應回調 * @param tag 網絡任務標識 */ public void okPostJSONRequest(String url, Map<String, String> headerMap, Map<String, String> parmMap, CacheControl cacheControl, Callback callback, String tag) { //獲取Builder Request.Builder builder = new Request.Builder().url(url); // 設置緩存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加請求頭信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } /** * 封裝參數 */ JSONObject jsonObject = new JSONObject(); if (parmMap != null && !parmMap.isEmpty()) { for (Map.Entry<String, String> entry :parmMap.entrySet()) { try { jsonObject.put(entry.getKey(), entry.getValue()); } catch (JSONException e) { e.printStackTrace(); } } } //獲取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),jsonObject.toString()); //獲取 Request Request request = builder.post(requestBody).build(); //獲取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 設置取消任務標籤 mCallHashMap.put(tag,call); //POST - JSON 發起請求 call.enqueue(callback); } /** * 移除 取消網絡任務 * * @param tag */ public void removeRequest(String tag) { //獲取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //若是包含KEY if (keyEntries.contains(tag)) { //獲取對應的Call Call call = mCallHashMap.get(tag); //若是沒有被取消 執行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除對應的KEY mCallHashMap.remove(tag); } }
在這裏,咱們將參數以map集合形式傳入,而後封裝成JSONObject對象,而後在構造請求體,
例 :
private void postJsonFunction() { //請求連接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //網絡請求標識 String tag = "getRequest"; //提交參數 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); paramMap.put("sex", "man"); //添加請求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostJSONRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //請求失敗回調方法 } @Override public void onResponse(Call call, Response response) throws IOException { //請求成功回調方法 } }, tag); }
經過抓包工具能夠看到提交的請求數據爲:
請求方式爲:
/** * 異步POST網絡請求 提交JSON數據 * * @param url 請求網絡連接 * @param headerMap 請求網絡添加頭信息 * @param JSONBody 請求網絡JSON字符串 * @param cacheControl 緩存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 響應回調 * @param tag 網絡任務標識 */ public void okPostJSONRequest(String url, Map<String, String> headerMap, String JSONBody, CacheControl cacheControl, Callback callback, String tag) { //獲取Builder Request.Builder builder = new Request.Builder().url(url); // 設置緩存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加請求頭信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //獲取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONBody); //獲取 Request Request request = builder.post(requestBody).build(); //獲取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 設置取消任務標籤 mCallHashMap.put(tag, call); //POST - JSON 發起請求 call.enqueue(callback); }
在這裏,咱們將直接構造好的JSON 字符串直接傳入到方法中,而後構造請求體
案例:
private void postJsonFunction1() { //請求連接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //網絡請求標識 String tag = "getRequest"; //提交參數 String JSONString = ""; JSONObject jsonObj = new JSONObject(); JSONArray jsonArray = new JSONArray(); try { for (int i = 0; i < 4; i++) { JSONObject jsono = new JSONObject(); jsono.put("userName", "xxx" + i); jsono.put("password", "123456" + i); jsonArray.put(jsono); } jsonObj.put("date", jsonArray); jsonObj.put("sex", "man"); }catch (Exception e){ } JSONString = jsonObj.toString(); //添加請求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostJSONRequest(url, heardMap,JSONString, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //請求失敗回調方法 } @Override public void onResponse(Call call, Response response) throws IOException { //請求成功回調方法 } }, tag); }
提交的請求數據爲:
{ "date": [{ "userName": "xxx0", "password": "1234560" }, { "userName": "xxx1", "password": "1234561" }, { "userName": "xxx2", "password": "1234562" }, { "userName": "xxx3", "password": "1234563" }], "sex": "man" }
也就是說在這裏咱們能夠定義任意結構層次的JSON數據
/** * 異步POST網絡請求 提交String數據 * * @param url 請求網絡連接 * @param headerMap 請求網絡添加頭信息 * @param string 請求網絡JSON字符串 * @param cacheControl 緩存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 響應回調 * @param tag 網絡任務標識 */ public void okPostStringRequest(String url, Map<String, String> headerMap, String string, CacheControl cacheControl, Callback callback, String tag) { //獲取Builder Request.Builder builder = new Request.Builder().url(url); // 設置緩存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加請求頭信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //獲取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"), string); //獲取 Request Request request = builder.post(requestBody).build(); //獲取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 設置取消任務標籤 mCallHashMap.put(tag, call); //POST - JSON 發起請求 call.enqueue(callback); }
案例:
private void postStringFunction() { //請求連接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //網絡請求標識 String tag = "getRequest"; //提交參數 String str = "this is String request data"; //添加請求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostStringRequest(url, heardMap, str, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //請求失敗回調方法 } @Override public void onResponse(Call call, Response response) throws IOException { //請求成功回調方法 } }, tag); }
提交的數據格式 :
提交的數據原型:
十、POST源碼簡述: