前言
App開發(fā)過(guò)程中必定使用網(wǎng)絡(luò)請(qǐng)求處理各種業(yè)務(wù)數(shù)據(jù)骤竹,使用成熟的網(wǎng)路組件能夠極大提高開發(fā)效率帝牡,實(shí)現(xiàn)業(yè)務(wù)的需求迭代。目前市面上可供選擇的網(wǎng)絡(luò)框架有AndroidAsync蒙揣、Volley靶溜、OkHttp、Retrofit等懒震,在選擇網(wǎng)絡(luò)組件時(shí)必定要考慮每個(gè)框架的特點(diǎn)罩息,依據(jù)自己業(yè)務(wù)合理選擇,先對(duì)這些框架做簡(jiǎn)要的分析比較个扰。
1 原生網(wǎng)絡(luò)請(qǐng)求
1.1 HttpClient
HttpClient是Apache Jakarta Common下的子項(xiàng)目瓷炮,用來(lái)提供高效的、最新的递宅、功能豐富的支持HTTP協(xié)議的客戶端編程工具包娘香,并且它支持HTTP協(xié)議最新的版本和建議。HttpClient已經(jīng)應(yīng)用在很多的項(xiàng)目中办龄,比如Apache Jakarta上很著名的另外兩個(gè)開源項(xiàng)目Cactus和HTMLUnit都使用了HttpClient烘绽。
示例代碼,基于httpclient-4.5.6.jar
public String doPost(String url){
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
String result = "";
try{
//通過(guò)默認(rèn)配置創(chuàng)建一個(gè)httpClient實(shí)例
httpClient = HttpClients.createDefault();
//創(chuàng)建httpPost遠(yuǎn)程連接實(shí)例
HttpPost httpPost = new HttpPost(url);
//httpPost.addHeader("Connection", "keep-alive");
httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader("Accept", "application/json");
//配置請(qǐng)求參數(shù)
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(35000) //設(shè)置連接主機(jī)服務(wù)超時(shí)時(shí)間
.setConnectionRequestTimeout(35000)//設(shè)置請(qǐng)求超時(shí)時(shí)間
.setSocketTimeout(60000)//設(shè)置數(shù)據(jù)讀取超時(shí)時(shí)間
.build();
//為httpPost實(shí)例設(shè)置配置
httpPost.setConfig(requestConfig);
//創(chuàng)建請(qǐng)求內(nèi)容
String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
StringEntity entity = new StringEntity(jsonStr);
httpPost.setEntity(entity);
//執(zhí)行post請(qǐng)求得到返回對(duì)象
response = httpClient.execute(httpPost);
//通過(guò)返回對(duì)象獲取返回?cái)?shù)據(jù)
HttpEntity entity = response.getEntity();
//通過(guò)EntityUtils中的toString方法將結(jié)果轉(zhuǎn)換為字符串
result = EntityUtils.toString(entity,"utf-8");
System.out.println(result);
}catch (Exception e){
e.printStackTrace();
}finally {
//關(guān)閉資源
if(response != null){
try {
response.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
if(httpClient != null){
try{
httpClient.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
}
return result;
}
1.2 HttpURLConnection
示例代碼
public String doPost(String URL){
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
HttpURLConnection conn = null;
try{
URL url = new URL(URL);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
//發(fā)送POST請(qǐng)求必須設(shè)置為true
conn.setDoOutput(true);
conn.setDoInput(true);
//設(shè)置連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
//獲取輸出流
out = new OutputStreamWriter(conn.getOutputStream());
String jsonStr = "{\"qry_by\":\"name\", \"name\":\"Tim\"}";
out.write(jsonStr);
out.flush();
out.close();
//取得輸入流土榴,并使用Reader讀取
if (200 == conn.getResponseCode()){
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null){
result.append(line);
System.out.println(line);
}
}else{
System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(out != null){
out.close();
}
if(in != null){
in.close();
}
}catch (IOException ioe){
ioe.printStackTrace();
}
}
return result.toString();
}
1.3 HttpClient與HttpURLConnection比較
2 主流網(wǎng)絡(luò)庫(kù)介紹
2.1 為什么要設(shè)計(jì)網(wǎng)絡(luò)庫(kù)诀姚?
Andorid主線程不允許做耗時(shí)操作响牛,所以在進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí)需要手動(dòng)開啟新線程做任務(wù)玷禽。處理請(qǐng)求時(shí)需要設(shè)置各種網(wǎng)絡(luò)參數(shù)赫段,在網(wǎng)絡(luò)返回時(shí)需要依據(jù)結(jié)果做不同的邏輯判斷,在失敗的情況下須考慮重試機(jī)制矢赁,在成功時(shí)須借助Handler機(jī)制通知UI現(xiàn)場(chǎng)做出變化糯笙,同時(shí)需要考慮結(jié)果的緩存事宜,所有這些都自己實(shí)現(xiàn)會(huì)帶來(lái)工作量的具體提升撩银,而且不能保障其性能和穩(wěn)定性给涕。
目前市面上成熟的網(wǎng)絡(luò)庫(kù)有效的解決了異步請(qǐng)求、線程池额获、緩存等問(wèn)題够庙,提供友好的API,方便使用者調(diào)用抄邀,降低開發(fā)難度耘眨,縮短開發(fā)周期。網(wǎng)絡(luò)組件一般完成如下事項(xiàng):
2.2 主流網(wǎng)絡(luò)庫(kù)對(duì)比
2.2.1 Android-Async-Http
目前 HttpClient 已經(jīng)被廢棄境肾,而 android-async-http 是基于 HttpClient 的剔难,我想可能也是因?yàn)檫@個(gè)原因作者放棄維護(hù)。
2.2.2 Volley
VolleyVolley 是 Google 官方出的一套小而巧的異步請(qǐng)求庫(kù)奥喻,該框架封裝的擴(kuò)展性很強(qiáng)偶宫,支持 HttpClient、HttpUrlConnection环鲤,甚至支持 OkHttp纯趋。Volley 里面封裝了 ImageLoader ,對(duì)于簡(jiǎn)單的需求可以使用冷离,對(duì)于稍復(fù)雜點(diǎn)的需求還是需要用到專門的圖片加載框架结闸。Volley 適合數(shù)據(jù)量不大,通信頻繁的網(wǎng)絡(luò)操作酒朵,不支持同步桦锄,不能post大數(shù)據(jù)。
2.2.3 OkHttp
OkHttp 是 Square 公司開源的針對(duì) Java 和 Android 程序蔫耽,封裝的一個(gè)高性能 http 請(qǐng)求庫(kù)结耀,它的職責(zé)跟 HttpUrlConnection 是一樣的,支持 spdy匙铡、http 2.0图甜、websocket 、GZIP鳖眼、HTTP 緩存黑毅、同步與異步,而且 OkHttp 封裝了線程池钦讳,封裝了數(shù)據(jù)轉(zhuǎn)換矿瘦,封裝了參數(shù)使用枕面、錯(cuò)誤處理等,能夠自動(dòng)處理常見的網(wǎng)絡(luò)問(wèn)題缚去,像二次連接潮秘、SSL的握手問(wèn)題。
在Android4.4的源碼中HttpURLConnection已經(jīng)替換成OkHttp實(shí)現(xiàn)了易结,SPDY是Google開發(fā)的基于TCP的傳輸層協(xié)議枕荞,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度搞动,優(yōu)化用戶的網(wǎng)絡(luò)使用體驗(yàn)躏精。OkHttp使用Okio來(lái)大大簡(jiǎn)化數(shù)據(jù)的訪問(wèn)與存儲(chǔ),Okio是一個(gè)增強(qiáng) java.io 和 java.nio的庫(kù)鹦肿。
2.2.4 Retrofit
Retrofit 是 Square 公司出品的默認(rèn)基于 OkHttp 封裝的一套 RESTful 網(wǎng)絡(luò)請(qǐng)求框架玉控,RESTful 是目前流行的一套 api 設(shè)計(jì)的風(fēng)格,并不是標(biāo)準(zhǔn)狮惜。Retrofit簡(jiǎn)化了網(wǎng)絡(luò)請(qǐng)求的流程高诺,提供不同的Json Converter實(shí)現(xiàn),提供RxJava支持碾篡,還有Dagger2比volley解耦更徹底虱而。
關(guān)鍵是想要用好這個(gè)框架,最好是和RxJava聯(lián)用开泽,否者和普通的網(wǎng)絡(luò)框架也沒什么區(qū)別牡拇。
參考資料:
[1] Android探索之HttpURLConnection網(wǎng)絡(luò)請(qǐng)求
[2] Java代碼發(fā)送Http的GET和POST請(qǐng)求
[3] Android開源:主流網(wǎng)絡(luò)請(qǐng)求庫(kù)對(duì)比 ★
[4] Android Http請(qǐng)求框架的選擇
[5] 六款值得推薦的網(wǎng)絡(luò)開源請(qǐng)求框架 √
[6] Android的開發(fā)之&論網(wǎng)絡(luò)加載框架