Android中HTTP相關的API

jopen 9年前發布 | 15K 次閱讀 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未修改的狀態。如果內容不變,則不下載。
  • 沒有緩存的響應需要服務器處理,然后這些請求被緩存下來。

對于低于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吧。

原文信息

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