一、HttpClient:
HttpClient本人用的比較少,然後進行了一些瞭解,主要有以下幾個方面:
- HttpClient是Apache的一個第三方網絡框架,對網絡請求封裝的比較完善,有衆多的api,比較穩定。
- 擴展性不強,android5.0被廢棄,6.0逐漸刪除。
- 創建HttpClient對象,對於get請求,再創建HttpGet對象,對於post請求,再創建HttpPost對象。
- 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HttpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
- 調用HttpClient對象的execute(HttpUriRequest request)發送請求,執行該方法返回一個HttpResponse。
- 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。
二、HttpURLConnection
- HttpURLConnection比較輕量級,對網絡請求的封裝沒有HttpClient完善,用起來也沒有那麼方便。
- HttpURLConnection對象不能直接構造,需要通過URL類中的openConnection()方法來獲得。
- 對HttpURLConnection對象的配置需要在connect方法執行之前完成。
- HttpURLConnection是基於HTTP協議的,底層通過socket通信實現,需要設置請求方式和超時。
- HttpURLConnection通過getInputStream()返回一個輸入流,從中獲取服務器對於HTTP請求的返回信息。對於post請求方式,需要通過getOutputStream()流寫入,寫入到緩衝區中。
- 由於HttpURLConnection調用 close() 函數會影響連接池,導致連接複用失效,若使用需要關閉keepAlive,極大的不方便,每次HTTP請求都有。
- HttpUrlConnection現在的底層實現是通過Okhttp
//開啓線程來發起網絡請求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.connect();
//如果是Post方式時
// String params = "abc";
// OutputStream out = connection.getOutputStream();
// out.write(params.getBytes());
// out.flush();
// out.close();
InputStream in = connection.getInputStream();
//下面對獲取到的輸入流進行讀取
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
response.append(line);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
//將服務器返回的結果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
// showResponse(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(connection != null){
connection.disconnect();
}
}
}
}).start();
三、Volley
- Volley適合處理數據量小,通信頻繁的網絡操作;在處理大數據量的請求時,表現不好,因爲在內部使用的是字節數組緩存池ByteArrayPool(維護了兩個List集合),每次從緩衝區取空間,不必每次存數據都進行內存分配,減少GC。
- Volley內部封裝了異步線程,可直接在主線程請求網絡並處理返回的結果。
- 容易擴展,支持HttpClient、HttpURLConnection、甚至OkHttp,也封裝了ImageLoader。
- Volley可以取消請求。
- 一個緩存線程,4個網絡線程。
關於Volley的詳細使用,可以去看我的另一篇文章:最簡單詳細的Volley使用解析。
四、okhttp
- 谷歌官方在6.0以後移除了httpClient,加入了okhttp
- okhttp是專注於提升網絡連接效率的http客戶端,支持連接同一地址的鏈接重用同一個socket,避免了每次都創建socket再斷開socket,通過連接池來減小響應延遲。
- okhttp支持SPDY(是谷歌開發的基於TCP的應用層協議,用於最小化網絡延遲,提升網絡速度,優化用戶的網絡使用體驗. SPDY並不是一種替代http的協議,只是對http的一種增強)。
- okhttp支持http和https,支持連接池、GZIP和HTTP緩存。
- 成熟的網絡請求解決方案,比HttpURLConnection更好用。
- OkHttp基於NIO和Okio,在性能上也就更快。
- 缺點是okhttp請求網絡切換回來是在線程裏面的,不是在主線程,不能直接刷新UI,需要我們手動處理。封裝比較麻煩。
okhttp發起網絡請求:
- 構建 OkHttpClient 客戶端
- 構建 Request 請求
- 創建 Call 對象,發起網絡請求
- 處理 Response 響應結果
使用:同步get請求
new Thread(new Runnable() {
@Override
public void run() {
try {
//構建okHttp客戶端
OkHttpClient client = new OkHttpClient();
//構建請求報文
Request request = new Request.Builder().url("https://www.baidu.com").build();
//發起同步請求,返回響應報文
Response response = client.newCall(request).execute();
//獲取響應體
String responseData = response.body().string();
showResponse(responseData);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
異步get請求
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS).build();
final Request request = new Request.Builder().url("https://www.baidu.com").get().build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("MainActivity",e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("MainActivity",Thread.currentThread().getName());
//運行在子線程中,所以必須在主線程中更改UI
showResponse(response.body().string());
}
});
番外篇:
- Retrofit也是Square公司開發的,默認基於OkHttp封裝的一套RESTful網絡請求框架,可以使用不同的http客戶端,同時支持RxJava,目前使用比較多的是Retrofit+OkHttp+RxJava+Dagger2。
- 對於Retrofit和OkHttp來說,肯定首選Retrofit,因爲Retrofit默認就是基於OkHttp進行的封裝。
- IO(阻塞式IO) 和 NIO(非阻塞式)的區別:如果從硬盤讀取數據,IO就是程序會一直等,數據讀完後才能繼續操作;NIO是你讀你的數據,程序接着往下執行,等數據處理完你再來通知我,然後再處理回調。 所以NIO當然要比IO的性能要好了。而 Okio是 Square 公司基於IO和NIO基礎上做的一個更簡單、高效處理數據流的一個庫。
- Retrofit2.0優化了很多地方,相比較Volley來說,Retrofit默認OkHttp,再結合RxJava的話,Retrofit應該更好一點。當然一般簡單項目可以使用Volley。
- RxVolley是基於Volley框架現在又比較流行的框架。RxVolley=Volley+RxJava+OkHttp。怎麼說呢,這個框架用起來還是很不錯的,不過我的瞭解現在還不夠深入,等着熟悉了之後再更新RxVolley的詳細使用。