大多數(shù)Android應用都需要連接網(wǎng)絡,使用HTTP來發(fā)送和接收數(shù)據(jù)。Android包含兩種HTTP客戶端:HttpURLConnection和Apache HTTP Client。它們都支持HTTPS,流的上傳和下載,超時配置,IPv6和連接池。
Apache HTTP客戶端
DefaultHttpClient和AndroidHttpClient都是適用于web瀏覽器的可擴展HTTP客戶端。它們有大量的、靈活的API。它們的實現(xiàn)穩(wěn)定,幾乎沒有bug。
但是大數(shù)量的API使得我們很難在不破壞兼容性的情況下對其改善,同時Google的Android團隊沒有積極致力于Apache HTTP客戶端。
HttpURLConnection
HttpURLConnection是一個通用的、輕量的、適用于大多數(shù)應用的HTTP客戶端。它的API量少,但主要的API使得我們可以穩(wěn)固地進行改善。
在Froyo之前,HttpURLConnection有一些令人沮喪的bug。尤其在一個可讀輸入流時調(diào)用close()會污染連接池。通過禁用連接池來解決這個問題:
private void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (Integer.parseInt(Build.VERSION.SDK < Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
在Gingerbread,添加了透明響應壓縮。HttpURLConnection會自動添加下面的header到發(fā)出的請求中,并且處理相應的響應:
Accept-Encoding: gzipf
使用這個需要配置Web服務器來對客戶端進行壓縮響應。
由于HTTP的Content-Length頭返回壓縮的大小,因此使用getContentLength()來給未壓縮數(shù)據(jù)定義緩存大小是錯誤的,而應該從響應中讀取字節(jié)直到InputStream.read()返回-1。
在Gingerbread中做了些關于HTTPS的提升。HttpsURLConnection嘗試連接Server Name Indication(SNI:允許多個HTTPS hosts共享一個IP地址)。它同時啟用了壓縮和會話許可證。如果連接失敗,它會自動不用這些特性嘗試。這樣使得當連接最新的服務器時HttpsURLConnection有效率,而不會破壞之前的兼容性。
在Ice Cream Sandwich,添加了一個響應緩存。當緩存建立了,HTTP請求將會是以下三種方式中的一種:
- 所有緩存響應將會直接從本地存儲獲取服務。因為沒有網(wǎng)絡連接需要建立,響應可以立即可用。
- 有條件地緩存響應必須通過webserver有它們的刷新有效期??蛻舳税l(fā)送一個請求“Give me /foo.png if it changed since yesterday”,然后服務器用更新后的內(nèi)容或者一個304 Not Modified狀態(tài)回復。如果內(nèi)容沒有改變將不會進行下載。
- 未緩存響應將會從網(wǎng)絡獲取服務。這些響應將會在之后存儲在響應緩存中。
使用反射來在支持的設備上啟用HTTP響應緩存。下面是示例代碼來在Ice Cream Sandwich上打開響應緩存而不影響之前的版本:
private void enableHttpResponseCache() {
try {
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
}
}
也應該配置Web Server來在HTTP響應上設置緩存頭。
哪個客戶端是最好的?
Apache HTTP客戶端在Eclair和Froyo上幾乎沒有bug,它是這些版本的最好選擇。
對于Gingerbread和之后的版本,HttpURLConnection是最好的選擇,它簡單的API和小體積使得很適合Android。透明壓縮和響應緩存減少了網(wǎng)絡流量,提升了速度,節(jié)省了電池。
原文鏈接:
http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Http客戶端的相關故事
- android-async-http內(nèi)部實現(xiàn)基于HttpClient。
- Volley在Gingerbread及之上使用HttpURLConnection,其他情況使用的HttpClient。
- Google在Android 6.0版本刪除了HttpClient相關API。