1. 程式人生 > >Android下的兩種http通訊機制介紹

Android下的兩種http通訊機制介紹

    Android網路通訊經常會用到http通訊機制,而基本上目前有兩個實現方式:HttpUrlConnection和HttpClient。

HttpUrlConnection和HttpClient的關係

在研究一些開源網路請求框架時發現在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。後來查閱資料發現Google官方在Android 2.3以後更推薦使用HttpURLConnection來在Android下進行Http通訊。

聯絡

大多數的Android應用程式都會使用HTTP協議來發送和接收網路資料,而Android中主要提供了兩種方式來進行HTTP操作,HttpURLConnection和HttpClient。這兩種方式都支援HTTPS協議、以流的形式進行上傳和下載、配置超時時間、IPv6、以及連線池等功能。

區別

1.HttpClient是apache的開源實現,而HttpUrlConnection是安卓標準實現,安卓SDK雖然集成了HttpClient,但官方支援的卻是HttpUrlConnection;

2.HttpUrlConnection直接支援GZIP壓縮;HttpClient也支援,但要自己寫程式碼處理;我們之前測試HttpUrlConnection的GZIP壓縮在傳大檔案分包trunk時有問題,只適合小檔案,不過這個BUG後來官方說已經修復了;

3.HttpUrlConnection直接支援系統級連線池,即開啟的連線不會直接關閉,在一段時間內所有程式可共用;HttpClient當然也能做到,但畢竟不如官方直接系統底層支援好;

4.HttpUrlConnection直接在系統層面做了快取策略處理,加快重複請求的速度。

具體實現


首先Android下訪問網路需要在Manifest檔案內加上以下訪問網路的許可權

<uses-permission android:name="android.permission.INTERNET"/>  

通過HttpUrlConnection來GET資料

/**
 * 通過HttpUrlConnection來get請求資料
 * 
 * @param url
 * @return result
 */
public static String getByHttpUrlConn
(String requestUrl) { StringBuffer strBuf; strBuf = new StringBuffer(); try { URL url = new URL(requestUrl); URLConnection conn = url.openConnection(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));// 轉碼。 String line = null; while ((line = reader.readLine()) != null) strBuf.append(line + " "); reader.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return strBuf.toString(); }

通過HttpUrlConnection來POST資料

/**
 * 通過HttpUrlConnection來post請求資料
 * 
 * @param url
 * @return result
 */
public static String postByHttpUrlConn(String url) {
    String result = null;
    HttpURLConnection urlConnection = null;  
try {  
    urlConnection = (HttpURLConnection) new URL(url).openConnection();  
    urlConnection.setDoInput(true);  
    urlConnection.setDoOutput(true);  
    urlConnection.setChunkedStreamingMode(0);  
    urlConnection.setRequestMethod("POST");  
    urlConnection.setRequestProperty("Content-Type", ("application/xml; charset=utf-8").replaceAll("\\s", ""));  
    urlConnection.setRequestProperty("Content-Length", String.valueOf(Xml.getBytes().length));  
    OutputStream out = urlConnection.getOutputStream();  
    out.write(Xml.getBytes());  
    out.close();  
    int responseCode = urlConnection.getResponseCode();  
    InputStream in = null;  
    if (responseCode == 200) {  
        in = new BufferedInputStream(urlConnection.getInputStream());  
    } else {  
        in = new BufferedInputStream(urlConnection.getErrorStream());  
    }  
    result = readInStream(in);  
} catch (MalformedURLException e) {  
    e.printStackTrace();  
} catch (IOException e) {  
    e.printStackTrace();  
} finally {  
    urlConnection.disconnect();  
} 
    return result;
}

預設的,不給urlConnection新增任何屬性的話是使用Get方法,如果用Post可以:urlConnection.setDoOutput(true);
urlConnection.setRequestMethod(“POST”);

當然還可以用setRequestProperty方法給請求新增:Host,Content-Type,Content-Lenth,Authentication等引數再使用Post的時候還有一個注意點在官方文件中提及的:上傳資料到伺服器時為了達到最好的效能,你可以在知道資料固定大小長度的情況下使用 setFixedLengthStreamingMode(int) 方法,或者在不知道長度的情況下使用setChunkedStreamingMode(int)。因為如果不這樣的話,HttpURLConnection 在發生請求之前是將資料全部放到記憶體裡面的,這樣浪費記憶體(會造成OutOfMemoryError)而且延時。這個東西再這裡詳細說了:http://www.mzone.cc/article/198.html

通過HttpClient來GET資料

public static String getByHttpClient(String baseUrl){
    String result = null;
    //先將引數放入List,再對引數進行URL編碼  
    List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();  
    params.add(new BasicNameValuePair("param1", "中國"));  
    params.add(new BasicNameValuePair("param2","value2"));  
    //對引數編碼  
    String param = URLEncodedUtils.format(params, "UTF-8");  
    //將URL與引數拼接  
    HttpGet getMethod = new HttpGet(baseUrl + "?" + param);  
    HttpClient httpClient = new DefaultHttpClient();  
    try {  
        HttpResponse response = httpClient.execute(getMethod); //發起GET請求  
        Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //獲取響應碼  
        result = EntityUtils.toString(response.getEntity(), "utf-8");
    } catch (ClientProtocolException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    } catch (IOException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }  
    return result;
}

通過HttpClient來POST資料

public static String postByHttpClient(String url){
    String result = null;
    //先將引數放入List,再對引數進行URL編碼  
    List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();  
    //和GET方式一樣,先將引數放入List  
    params = new LinkedList<BasicNameValuePair>();  
    params.add(new BasicNameValuePair("param1", "Post方法"));  
    params.add(new BasicNameValuePair("param2", "第二個引數"));  

    try {  
        HttpPost postMethod = new HttpPost(url);  
        HttpClient httpClient = new DefaultHttpClient();  
        //將引數填入POST Entity中  
        postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8")); 

        HttpResponse response = httpClient.execute(postMethod); //執行POST方法  
        Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //獲取響應碼  
        //獲取響應內容  
        result = EntityUtils.toString(response.getEntity(), "utf-8"); 

    } catch (UnsupportedEncodingException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    } catch (ClientProtocolException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    } catch (IOException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    }   
        return result;
}

Ending

以上部分程式碼我沒有實際執行測試,如果有問題,請留言評論