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
以上部分代码我没有实际运行测试,如果有问题,请留言评论