[Android官方開發者博客.翻譯]Android的HTTP客戶端

Android的HTTP客戶端 html

原文地址: java

http://android-developers.blogspot.com/2011/09/androids-http-clients.html android

[本文由來自Dalvik團隊的Jesse Wilson提交。--Tim Bray] web

大多數須要網絡鏈接的Android應用都會使用HTTP來傳輸數據。Android自帶了兩個HTTP客戶端:HttpURLConnection和Apache HTTP Clinent。它們都支持HTTPS,文件上傳下載,配置超時, apache

IPV6及鏈接池。 瀏覽器

Apache HTTP Client 緩存

DefaultHttpClient及其類似的AndroidHttpClient都是HttpClient的擴展適用於Web瀏覽器。它們有豐富的可擴展的API,同時也很穩定沒有什麼Bug。 服務器

可是這裏重量級的API讓咱們難以修改後保證它的兼容性,由於Android團隊在Apache HTTP Client中並無什麼開發者。 網絡


HttpURLConnection session

HttpURLConnection是一個通用的,輕量級的適用於絕大多數應用的HTTP客戶端。這個類比較底層,但咱們能夠很容易的穩步修改它的關鍵的API。

在Froyo(2.2)以前,HttpURLConnection有幾個煩人的Bug,特別是,在一個可讀的InputStream中調用close()會

污染鏈接池,一個解決方案就是在低android版本中禁用鏈接池。


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(2.3)中,咱們添加了隱式的壓縮響應。HttpURLConnection將自動將如下的請求頭部添加到鏈接請求中,而後處理相應的請求:


Accept-Encoding:gzip


爲了充分利用這一點,你須要配置你的服務器爲支持這一請求頭的客戶端開啓壓縮響應。若是壓縮響應有問題,

你能夠參考HttpURLConnection來禁用它。

由於HTTP客戶端的Content-Length頭部返回的是壓縮後的大小,因此使用getContentLength()來得到解壓後的數據塊的大小是錯誤的。你應該從響應中讀取字節直到InputStream.read()返回-1。

同時咱們對在Gingerbread中的HTTPS鏈接作了一些優化,當HttpsURLConnection嘗試鏈接SNI(Server Name Indication)將容許多個hosts共享一個IP地址。一樣支持壓縮和Session tickets。若是鏈接失敗,將自動重試(it is automatically retried without these features)。這使得HttpURLConnection在鏈接新的服務器時更有效,同時不破壞向下兼容。

在Ice Cream Sandwich(4.X)中,咱們添加了響應緩存。有了緩存,HTTP請求就會知足下面三種方式:

 (1)徹底緩存的響應將直接從本地存在中得到。由於無需進行網絡鏈接 ,這樣的響應能夠立刻得到。

 (2)條件緩存的響應必須到服務器驗證是否過時,客戶端發送一個請求如"給我 /foo.png 若是從昨天后發生了改變的話",而後服務器響應返回更新的內容 或者一個304 Not Modified狀態。若是內容沒有更新,則將不會下載 。

 (3)非緩存的響應將從web端得到,這些請求會存儲在響應緩存中以務後用。


能夠利用反射來在支持的設備中開啓HTTP 響應緩存 。下面的代碼將在4.0以後的版本的開啓響應緩存 。而不會影響以前的版本。


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) {
    }
}


同時你須要配置你的服務器來在HTTP響應中設置緩存頭部。


哪個客戶端最好?

在Eclair(2.1)和Froyo(2.2)中,Apache HTTP Client(相比HttpURLConnection)沒有什麼Bug,

對於這些發行版,它是最好的選擇。

對於 Gingerbread(2.3)及以後的版本。HttpURLConnection是最好的選擇。它的簡單輕量最適合android。

壓縮,緩存響應以減小網絡鏈接,提高速度,省電,新的應用應該使用HttpURLConnection,它也是咱們將着力點。

PS:決定爲HttpURLConnection寫一點封裝,因此看了下官方博客,見沒有翻譯,以爲還不錯,就翻譯了下。

考慮到有些同窗不能訪問原文,原文以下:


Android’s HTTP Clients

[This post is by Jesse Wilson from the Dalvik team. —Tim Bray]


Most network-connected Android apps will use HTTP to send and receive data. Android includes two HTTP clients: HttpURLConnection and Apache HTTP Client. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6 and connection pooling.

Apache HTTP Client

DefaultHttpClient and its sibling AndroidHttpClient are extensible HTTP clients suitable for web browsers. They have large and flexible APIs. Their implementation is stable and they have few bugs.

But the large size of this API makes it difficult for us to improve it without breaking compatibility. The Android team is not actively working on Apache HTTP Client.

HttpURLConnection

HttpURLConnection is a general-purpose, lightweight HTTP client suitable for most applications. This class has humblebeginnings, but its focused API has made it easy for us to improve steadily.

Prior to Froyo, HttpURLConnection had some frustrating bugs. In particular, calling close() on a readable InputStream could poison the connection pool. Work around this by disabling connection pooling:

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");     } }

In Gingerbread, we added transparent response compression. HttpURLConnection will automatically add this header tooutgoing requests, and handle the corresponding response:

Accept-Encoding: gzip

Take advantage of this by configuring your Web server to compress responses for clients that can support it. If response compression is problematic, the class documentation shows how to disable it.

Since HTTP’s Content-Length header returns the compressed size, it is an error to use getContentLength() to size buffers for the uncompressed data. Instead, read bytes from the response until InputStream.read() returns -1.

We also made several improvements to HTTPS in Gingerbread. HttpsURLConnection attempts to connect with Server Name Indication (SNI) which allows multiple HTTPS hosts to share an IP address. It also enables compression and session tickets. Should the connection fail, it is automatically retried without these features. This makes HttpsURLConnection efficient when connecting to up-to-date servers, without breaking compatibility with older ones.

In Ice Cream Sandwich, we are adding a response cache. With the cache installed, HTTP requests will be satisfied in one of three ways:

  • Fully cached responses are served directly from local storage. Because no network connection needs to be made such responses are available immediately.

  • Conditionally cached responses must have their freshness validated by the webserver. The client sends a request like 「Give me /foo.png if it changed since yesterday」 and the server replies with either the updated content or a304 Not Modified status. If the content is unchanged it will not be downloaded!

  • Uncached responses are served from the web. These responses will get stored in the response cache for later.

Use reflection to enable HTTP response caching on devices that support it. This sample code will turn on the response cache on Ice Cream Sandwich without affecting earlier releases:

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) {     } }

You should also configure your Web server to set cache headers on its HTTP responses.

Which client is best?

Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases.

For Gingerbread and better, HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android.Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.

相關文章
相關標籤/搜索