Android網路請求:OkHttp實戰
android網路請求是個耗時的操作,一定要在子執行緒中執行,新增網路許可權,目前有很多流行的網路框架。比如okhttp,volley,xutils等等。今天主要介紹okhttp的使用,後續分享給多,比如socket網路請求,檔案上傳下載。
一,HTTP協議的主要特點
HTTP協議的主要特點可概括如下:
1.支援客戶/伺服器模式。
2.簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。
3.靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加以標記。
4.無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
詳見原文:
二,OKHttp介紹
An HTTP & HTTP/2 client for Android and Java applications. For more information see the website and the wiki.前往OkHttp官網
使用okhttp很簡單,它的請求/響應 API設計,運用了流利的builder,確保方式多樣而又固定,支援非同步請求和回撥。它支援android 2.3或以上,jdk版本要求不低於1.7。
okhttp的主要特點:
- HTTP/2支援共享一個socket,傳送多個請求給相同的主機。
- 連線池減少了請求的潛在因素。
- 明顯的GZIP壓縮下載大小。
- 響應快取避免網路重複請求。
確保所有的網路請求只有一個OkHttpClient例項,可以用單例模式。也可以如下:
public static OkHttpClient okHttpClient = new OkHttpClient();
okhttp傳送請求,封裝的方法,必須在子執行緒執行。另外回撥方法是在子執行緒中,要更新UI必須在主執行緒,自己處理。下面的方法中的OkHttpClient例項統一用上面生成的。
三,okhttp傳送get請求
演示基本的用法,不懂的地方可以github下載原始碼研究。
//OKHTTP GET
public static String get(String url){
Request request = new Request.Builder().url(url).build();
Response response = null;
try {
response = new OkHttpClient().newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
四,OKHttp構建RequestBody
傳送post的請求,比較普遍。無論有一個引數,多個引數,或者檔案上傳,都可以構建特定的RequestBody傳送請求。
1.傳送一個鍵值對。
RequestBody requestBody = RequestBody.create(MediaType.parse("UTF-8"),"param=value");
2.傳送多個引數,構建表單一樣的請求引數。
RequestBody requestBody = new FormBody.Builder()
.add("param1", "value1")
.add("param12", "value2")
.build();
3. post json字串
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, json);
4. 檔案上傳
MediaType,檔案型別標示,通常”application/octet-stream”就可以,比如jpg圖片,可以MediaType.parse(“image/jpg”)。表單引數根據專案需要自行調整。
final MediaType mediaType = MediaType.parse("application/octet-stream");
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data"));
builder.addFormDataPart("description", description);
builder.addFormDataPart("file", fileName, RequestBody.create(mediaType, uploadFile));
//構建請求體
RequestBody requestBody = builder.build();
五,傳送的post請求的方法
//使用Request的post方法來提交請求體RequestBody
public static String post(String url, RequestBody requestBody) throws IOException {
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
六,Headers相關。
先看官方對header和addHeader兩種方法的解釋:
/**
* Sets the header named {@code name} to {@code value}. If this request already has any headers
* with that name, they are all replaced.
*/
public Builder header(String name, String value) {
headers.set(name, value);
return this;
}
/**
* Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued
* headers like "Cookie".
*
* <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding},
* OkHttp may replace {@code value} with a header derived from the request body.
*/
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
意思就是說,header是給已有的請求頭設定一個值,
addHeader是新增新的請求頭,value的值可以有多個(以英文”,”分開)。例如:
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
LogUtils.debug("Server:"+response.header("Server"));
LogUtils.debug("Date: " + response.header("Date"));
LogUtils.debug("Vary: " + response.headers("Vary"));
}
返回結果:
Server: GitHub.com
Sat, 30 Apr 2016 01:24:48 GMT
Vary: [Accept, Accept-Encoding]
七,總結
okhttp是目前比較流行的網路框架,開源專案,本文介紹了本人一些常用的用法,不到之處望留言指出。對比了一些網路框架,還是挺讚的。
有時間再研究研究原始碼,未完待續,歡迎交流,杜乾,Dusan,Q 291902259。