OKHttp的介紹和基本用法
嗨,大家好。又和大家見面了,今天我和大家一起來學習一下OKHttp。
OKHttp是基於Http協議上的網路通訊,說白了就是Http協議。Http的功能OKHttp都有。那就問題來了,既然有了Http,這 強大的協議,為什麼還需要有OKHttp等將Http封裝的架包呢?其實程式設計是一個工作量大,工作重複性普遍的工作。程式設計人員都不喜歡做重複性的工作和處理Bug。個人感覺OKHttp就是基於這一系列的因素。所以OKHttp就誕生了。
OkHttp由於基於Http協議,所以http協議都支援。例如請求報文,響應報文,所有的請求方法等多做了很好的的處理。所以有關Http的知識就不詳細講解了,讀者可以自己去查詢資料瞭解一下。下面介紹使用OkHttp訪問網路。
其實使用OKHttp訪問網路很簡單,主要通過以下幾步:
1、初始化OKHttpClient例項
注:OKHttpClient在整個專案中使用單例模式,儘量直接new例項
//初始化OkHttpClient,OkHttpClient將採用單例模式 private static OkHttpClient okHttpClient = new OkHttpClient();2、初始化RequestBody例項,用於封裝請求的內容(PS:如果使用get請求可以直接省略該步驟)
//初始化RequestBody,用於儲存我訪問網路的請求資訊 RequestBody requestBody = RequestBody.create(JSONTYPE, requestContent);
3、初始化Request例項,用於封裝請求資訊
Request request = builder.url(url).build();
4、初始化Call例項,用於訪問網路
//初始化Call物件,用於訪問網路 Call call = okHttpClient.newCall(request);
5、訪問網路,OKhttp訪問網路提供了兩種方法
5.1、同步方法,返回Response物件,該物件封裝了網路資源資訊
//初始化Response物件,用於顯示訪問網路的響應頭資訊 Response response = call.execute();
5.2、非同步方法 (PS:非同步方法採用Callback介面回撥機制)
/* * 採用非同步方法訪問網路,返回響應報文資訊* */ public void enqueue(String url, Callback callback, String requestContent) { if (requestContent == null || "".equals(requestContent)) { //採用非同步get方法訪問網路 Request request = this.getRequest(url); //初始化Call物件,用於網路連線 Call call = okHttpClient.newCall(request); //採用非同步訪問網路 call.enqueue(callback); } else { //採用非同步post方法訪問網路 Request request = this.getRequest(url, requestContent); //初始化Call物件,用於網路連線 Call call = okHttpClient.newCall(request); call.enqueue(callback); } }
6、通過Response獲得網路資源
//初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法 ResponseBody body = response.body(); //以字串的形式獲得網路 result = body.string(); //以字元流的形式獲得網路 //body.charStream(); //以位元組的形式獲得網路 // body.bytes(); //以位元組流的形式獲得網路 //body.byteStream();
//獲得響應頭 Headers headers = response.headers(); //遍歷響應頭資訊 for (int i = 0; i < headers.size(); i++){ Log.d("tag",headers.name(i) + "--->" + headers.value(i)); }
通過以上的步驟就可以訪問網路了,很簡單嘛。但別以為OKHttp就只有這點功能,我這裡僅僅簡單介紹一下,幫助大家引進門,最好的學習方法就是看APi,看原始碼學習,瞭解大神的程式設計思想。
下面我將我學習OKHttp過程編寫的工具類copy出來,提供大家學習。
/* * * 該工具類採用單例模式* */ public class OkHttpUtils { //初始化OkHttpClient,OkHttpClient將採用單例模式 private static OkHttpClient okHttpClient = new OkHttpClient(); //初始化OkHttpUtils private static OkHttpUtils okHttpUtils = new OkHttpUtils(); //傳送請求訊息為Json型別 private static final MediaType JSONTYPE = MediaType.parse("application/*; charset=utf-8"); //構造私有的構造器,使外部不能直接建立例項 private OkHttpUtils() { } //採用單例模式中餓漢模式 public static OkHttpUtils getInstance() { return okHttpUtils; } //採用類方法獲得單一的OkHttpClient例項 public static OkHttpClient getOkHttpClient() { return okHttpClient; } /* * 獲得get方法Request的請求資訊 * */ private Request getRequest(String url) { return getRequest(url, null); } /* * 獲取響應頭 * */ public void getHeader(String url) { getHeader(url, null); } /* * 獲取響應頭 * */ public void getHeader(String url, String requestContent) { //初始化Request物件用於封裝請求訊息 Request request = this.getRequest(url, requestContent); try { //訪問網路,獲得響應資訊 Response response = this.execute(request); //獲得響應頭 Headers headers = response.headers(); //遍歷響應頭資訊 for (int i = 0; i < headers.size(); i++){ Log.d("tag",headers.name(i) + "--->" + headers.value(i)); } } catch (IOException e) { e.printStackTrace(); } } /* * call.execute()訪問網路,返回響應報文資訊 * */ private Response execute(Request request) throws IOException { //初始化Call物件,用於訪問網路 Call call = okHttpClient.newCall(request); //初始化Response物件,用於顯示訪問網路的響應頭資訊 Response response = call.execute(); return response; } /* * 採用非同步方法訪問網路,返回響應報文資訊 * */ public void enqueue(String url, Callback callback) { enqueue(url, callback, null); } /* * 採用非同步方法訪問網路,返回響應報文資訊 * */ public void enqueue(String url, Callback callback, String requestContent) { if (requestContent == null || "".equals(requestContent)) { //採用非同步get方法訪問網路 Request request = this.getRequest(url); //初始化Call物件,用於網路連線 Call call = okHttpClient.newCall(request); //採用非同步訪問網路 call.enqueue(callback); } else { //採用非同步post方法訪問網路 Request request = this.getRequest(url, requestContent); //初始化Call物件,用於網路連線 Call call = okHttpClient.newCall(request); call.enqueue(callback); } } /* * 獲得post方法的Request請求資訊,當requestContent資訊為null時,預設為get請求 * */ private Request getRequest(String url, String requestContent) { if ("".equals(requestContent) || requestContent == null) { //定義Rquest物件,封裝訪問網路的請求資訊 //new Request.Builder()建立Request的內部類Builder的物件,預設通過get方法訪問網路 Request.Builder builder = new Request.Builder(); //關聯訪問網路的url,並將其轉換為Request物件 Request request = builder.url(url).build(); return request; } else { //初始化RequestBody,用於儲存我訪問網路的請求資訊 RequestBody requestBody = RequestBody.create(JSONTYPE, requestContent); //初始化Request,用於封裝請求報頭 Request request = new Request.Builder().url(url).post(requestBody).build(); return request; } } //OkHttpClient的get方法 public Object get(String url) throws IOException { Object result = null; //關聯訪問網路的url,並將其轉換為Request物件 Request request = this.getRequest(url); Response response = this.execute(request); //檢測網路是否連線成功 if (response.isSuccessful()) { //獲取網連線資訊 String mess = response.message(); Log.d("tag", "mess = " + mess); //初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法 ResponseBody body = response.body(); //以字串的形式獲得網路 result = body.string(); //以字元流的形式獲得網路 //body.charStream(); //以位元組的形式獲得網路 // body.bytes(); //以位元組流的形式獲得網路 //body.byteStream(); } else { //如果沒有連線成功則丟擲io異常,答應出錯誤碼 throw new IOException("Unexcepted code = " + response.code()); } return result; } //OkHttpClient的get方法 public Object post(String url, String requestContent) throws IOException { String result = null; //初始化Request,用於封裝請求報頭 Request request = this.getRequest(url, requestContent); //訪問網路,返回相應報文 Response response = this.execute(request); //檢測網路是否連線成功 if (response.isSuccessful()) { //獲取網連線資訊 String mess = response.message(); Log.d("tag", "mess = " + mess); //初始化ResponseBody物件,用於封裝網路資源,該實體用許多訪問網路資源的方法 ResponseBody body = response.body(); //以字串的形式獲得網路 result = body.string(); //以字元流的形式獲得網路 //body.charStream(); //以位元組的形式獲得網路 // body.bytes(); //以位元組流的形式獲得網路 //body.byteStream(); } else { //如果沒有連線成功則丟擲io異常,答應出錯誤碼 throw new IOException("Unexcepted code = " + response.code()); } return result; } }
PS: 以上程式碼可以Copy在專案中直接執行
最後感謝大家的閱讀,由於本人是菜鳥,知識有限,有錯誤的地方歡迎大家提出。