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
以上部分程式碼我沒有實際執行測試,如果有問題,請留言評論