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