在Android上使用Http客戶端的選擇(譯文) – Android移動開發技術文章_手機開發 Android移動開發教學課程

翻譯來源於http://blog.publicobject.com/

       大多數有網絡連接的Android應用會使用HTTP協議發送和接收數據。Android包含兩種Http客戶端類, HttpURLConnection和Apache HttpClient。這兩者都支持HTTPS,streaming 上傳與下載,配置超時時間,IPv6, 以及連接池。

Apache Http Client

DefaultHttpClient 和它的兄弟類AndroidHttpClient是適用於web瀏覽器的可擴展的Http客戶端。它們有大量的靈活的API,實現比較穩定,很少有bug。但是, 其龐大的API使我們很難去改進而不破壞其兼容性。 Android團隊現在已不活躍與Apache HttpClient的工作上瞭。

HttpURLConnection

HttpURLConnection是一個可以適用於各類應用的通用輕量級的Http客戶端。該類開始較為簡陋,但其關註的API讓我們容易平穩地改進它。 在Froyo(2.2)之前,HttpURLConnection有一些令人沮喪的的bug。尤其是在一個可讀的InputStream上調用close()將會阻礙連接池。為瞭解決這個bug隻能關掉連接池。

 

1  private void disableConnectionReuseIfNecessary() {

2     // HTTP connection reuse which was buggy pre-froyo

3     if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {

4         System.setProperty("http.keepAlive", "false");

5     }

6 }

  

 

在Gingerbread(2.3),我們增加瞭透明的回應(response)壓縮。HttpURLConnection將自動地將“Accept-Encoding: gzip”頭字段添加到請求(request)中,並處理相應的回應。 通過更改你的Web服務器配置,實現對支持的客戶端返回壓縮後的數據。如果壓縮出瞭問題, 類文檔將提供關掉它的方法。

       由於HTTP的Content-Length頭字段返回的是壓縮後的大小,使用getContentLength()去分配解壓縮後數據buffer 的大小就是錯誤的。 應該從response中讀字節直到InputStream.read()返回值為-1。

       我們還在Gingerbread上對HTTPS作出瞭一些改進。HttpsURLConnection嘗試以Server Name Indication(SNI)連接, SNI允許多個HTTPS host共享同一個IP地址。HttpsURLConnection也同樣可以使用壓縮和session ticket特性。,一旦連接失敗,它會自動不去使用這些特性重試。這使得HttpsURLConnection可以有效地連接最新的服務器,同時不破壞對老舊服務器的兼容性。

在Ice Cream Sandwich(4.0),我們增加瞭response cache。安裝瞭cache後,HTTP 請求以以下三種方式之一處理:

l 完全的cache的response將直接從本地存儲中獲取。因為不需要網絡連接,此類response可以立即得到。

l 有條件cache的response必須在Web服務器驗證一下cache的有效性。客戶端發送一個請求,比如“如果/foo.png從昨天起有變化則給我新的圖片” , 服務端的response要麼是更新後的內容,要麼是304 沒有修改狀態碼。如果內容是沒有改變的,就不需要下載瞭。

l 沒有cache的response將從服務器上獲取。得到這些response之後會存儲到cache以便將來使用。

使用反射機制來使用Https response cache功能。以下示例代碼將會在Ice Cream Sandwich上打開response cache功能而不影響到之前的版本:

 

1 private void enableHttpResponseCache() {

 2     try {

 3         long httpCacheSize = 10 * 1024 * 1024; // 10 MiB

 4         File httpCacheDir = new File(getCacheDir(), "http");

 5         Class.forName("android.net.http.HttpResponseCache")

 6             .getMethod("install", File.class, long.class)

 7             .invoke(null, httpCacheDir, httpCacheSize);

 8     } catch (Exception httpResponseCacheNotAvailable) {

 9     }

10 }

 

 

當然,你也需要更改你的Web服務器配置,在其Http response中設置cache頭字段。

哪一種http客戶端最好?

Apache HTTP client在Eclair(2.1)和Froyo(2.2)上bug更少,在這些系統版本上將是最佳選擇。

       從Gingerbread(2.3)起,HttpURLConnection將是最佳選擇,其API簡單,小巧,非常適合於Android。透明的壓縮及response cache減少瞭網絡流量,改進瞭網絡速度,也就更省電。 新的應用將應該使用HttpURLConnection, 這是我們以後花費精力去探索的地方。

 摘自 http://www.naitiz.com/index.php/use_http_client_on_android_94.html

發佈留言