Android中HTTP相關的API

cey6 10年前發布 | 19K 次閱讀 Android Android開發 移動開發

Android中大多數應用都會發送和接受HTTP請求,在Android API中主要由兩個HTTP請求的相關類,一個是HttpURLConnection,另一個是Apache HTTP Client。這兩個類實現的HTTP請求都支持HTTPS協議,基于流的上傳和下載,可配置超時時間,IPv6和連接池。

Apache HTTP Client

DefaultHttpClient和同類的AndroidHttpClient都是可擴展的類。它們有大量且靈活的API,適用于網頁瀏覽器開發。同時它們比較穩定并且bug較少。但是繁多的API的現實下,對其改善與保持兼容性不可得兼,明顯Android團隊的精力已然不在Apache HTTP Client。

HttpURLConnection

HttpURLConnection是一個通用,輕量的實現,可以滿足大多數的程序進行HTTP請求。這個類雖然一開始比較簡陋,但是其主要的幾個API使得我們更容易進行穩定改善。

連接池污染

在凍酸奶(Android 2.2)之前,HttpURLConnection有著一些煩人的bug。最煩人的就是調用一個可讀的InputStream的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");
    }
}


壓縮數據與大小

從2.3開始,我們默認對返回的響應進行了壓縮,HttpURLConnection會自動為發出去的請求加上Accept-Encoding: gzip這個頭信息。如果gzip壓縮的響應有問題,可以通過下面代碼禁用gzip。

urlConnection.setRequestProperty("Accept-Encoding", "identity");


由于HTTP中的Content-Length頭信息返回的是壓縮后的大小,所以我們不能使用getContentLength()來計算未壓縮數據的大小。正確的做法應該是讀取HTTP響應中的字節,直到InputStream.read()方法返回為-1.

HTTPs改進

從Gingerbread開始,增加了對HTTPs鏈接的優化。在進行HTTPs請求之前,HttpsURLConnection會嘗試使用服務器名字指示(Server Name Indication),這種技術可以讓多個HTTPs主機共享一個IP地址。在HTTPs請求中,HttpsURLConnection也支持壓縮和會話標簽(Session Tickets)。一旦連接失敗,HttpsURLConnection會不使用上面的三個特性進行重試。這樣即可以保證在連接時高效率地連接到最新的服務器,也可以在不破壞兼容性的同時連接到舊服務器。

響應緩存

從4.0開始,HttpURLConnection引入了響應緩存機制。一旦緩存創建,后續的HTTP請求會按照下面情況處理

  • 完全緩存的響應會直接從本地存儲中讀取,響應很快,不需要網絡連接。
  • 有條件的緩存必須由服務端進行freshness驗證,比如client發出一個請求,如”Give me /foo.png if it changed since yesterday”,然后服務器端要么返回最新的內容,要么返回304未修改的狀態。如果內容不變,則不下載。
  • 沒有緩存的響應需要服務器處理,然后這些請求被緩存下來。
  • </ul>

    對于低于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緩存相關的頭信息。

    哪家強

    在2.3之前的版本,Apache的HTTP請求響應實現比較穩定,bug也少,所以在那些版本上它的最好。

    但是在2.3之后,毫無疑問,HttpURLConnection是最好的。它API精簡實用,默認支持壓縮,響應緩存等。最重要的這是Android團隊重點投入的,而Apache的版本已經被拋棄了。所以還是使用HttpURLConnection吧。

    原文信息

 本文由用戶 cey6 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!