HttpClient vs HttpURLConnection

大多數(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客戶端的相關故事

  1. android-async-http內(nèi)部實現(xiàn)基于HttpClient。
  2. Volley在Gingerbread及之上使用HttpURLConnection,其他情況使用的HttpClient。
  3. Google在Android 6.0版本刪除了HttpClient相關API。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,040評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,563評論 19 139
  • 轉(zhuǎn)自: Android4種網(wǎng)絡連接方式HttpClient、HttpURLConnection、OKHttp和V...
    yabin小站閱讀 5,583評論 0 40
  • 今天早早的起床,來到了店里。好長時間沒回家,對家已很陌生了。我知道我與家人的距離。我在追溯過往經(jīng)歷中發(fā)現(xiàn)了自己的卡...
    王澤華wzhwzh閱讀 171評論 0 0
  • 中秋節(jié)來了,那天早上先背書,寫了一些作業(yè)。然后去香辣蝦店吃中午飯。去沃爾瑪超市購物,看到了書本,原本要購物的我去讀...
    楊斯茹閱讀 333評論 0 0

友情鏈接更多精彩內(nèi)容