android网络应用(二)——HttpURLConnection和HttpClient
2016-06-22 11:18
591 查看
HttpURLConnection
获取HttpURLConnection实例对象
请求方法一get
请求方法二post
HttpClient
获取HttpClient抽象类
GET 请求创建一个 HttpGet 对象
POST请求HttpPost 对象
execute
实例
网络编程的最佳实践
抽取公有部分设置快速使用网络功能类
改进版
二者区别
2、接下来设置延时设置或者服务器希望得到的一些消息头!!!
3、获取输入流,并进行读取
4、关闭连接
5、实例
网络请求通常都是属于耗时操作,而 sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用 sendHttpRequest()方法的时候使得主线程被阻塞住。PS:现在网络请求都要求不能在主线程中启用。
在sendHttpRequest()方法内部开启一个线程不就解决这个问题了吗?其实不是像你想象中的那么容易,因为如果我们在 sendHttpRequest()方法中开启了一个线程来发起 HTTP 请求,那么服务器响应的数据是无法进行返回的,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器还来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。
解决方法:Java 的回调机制
这两个方法都带有参数,onFinish()方法中的参数代表着服务器返回的数据,而 onError()方法中的参数记录着错误的详细信息。
当服务器成功响应的时候我们就可以在 onFinish()方法里对响应数据进行处理了,类似地,如果出现了异常,就可以在 onError()方法里对异常情况进行处理。如此一来,我们就巧妙地利用回调机制将响应数据成功返回给调用方了。另外需要注意的是,onFinish()方法和 onError()方法最终还是在子线程中运行的,因此我们不可以在这里执行任何的 UI 操作。
获取HttpURLConnection实例对象
请求方法一get
请求方法二post
HttpClient
获取HttpClient抽象类
GET 请求创建一个 HttpGet 对象
POST请求HttpPost 对象
execute
实例
网络编程的最佳实践
抽取公有部分设置快速使用网络功能类
改进版
二者区别
HttpURLConnection
获取HttpURLConnection实例对象
URL url = new URL("http://www.baidu.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
请求方法一——get
1、设置请求方法connection.setRequestMethod("GET");
2、接下来设置延时设置或者服务器希望得到的一些消息头!!!
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
3、获取输入流,并进行读取
InputStream in = connection.getInputStream();
4、关闭连接
connection.disconnect();
5、实例
// 开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
// 下面对获取到的输入流进行读取
BufferedReader reader = new BufferedReader(newInputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
// 将服务器返回的结果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
//注意权限 <uses-permission android:name="android.permission.INTERNET" />
请求方法二——post
和get差距不大,但是要注意参数以及提交数据设置connection.setRequestMethod("POST"); DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.writeBytes("username=admin&password=123456");
HttpClient
获取HttpClient(抽象类)
HttpClient 是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient 的实例。HttpClient httpClient = new DefaultHttpClient();
GET 请求——创建一个 HttpGet 对象
HttpGet httpGet = new HttpGet("http://www.baidu.com"); httpClient.execute(httpGet);
POST请求——HttpPost 对象
要创建一个 HttpPost 对象,并传入目标的网络地址,如下所示: HttpPost httpPost = new HttpPost("http://www.baidu.com"); 然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的UrlEncodedFormEntity传入,如下所示: List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", "admin")); params.add(new BasicNameValuePair("password", "123456")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8"); httpPost.setEntity(entity); httpClient.execute(httpPost);
execute()
执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 接下来在这个 if 判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity 实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity 转换成字符串即可,如下所示: HttpEntity entity = httpResponse.getEntity(); //String response = EntityUtils.toString(entity); //上面会出现中文乱码 String response = EntityUtils.toString(entity, "utf-8"); }
实例
Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8"); Message message = new Message(); message.what = SHOW_RESPONSE; // 将服务器返回的结果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); } } }).start(); }
网络编程的最佳实践
抽取公有部分,设置快速使用网络功能类
public class HttpUtil {
public static String sendHttpRequest(String address) {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
//调用 String address = "http://www.baidu.com"; String response = HttpUtil.sendHttpRequest(address);
网络请求通常都是属于耗时操作,而 sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用 sendHttpRequest()方法的时候使得主线程被阻塞住。PS:现在网络请求都要求不能在主线程中启用。
在sendHttpRequest()方法内部开启一个线程不就解决这个问题了吗?其实不是像你想象中的那么容易,因为如果我们在 sendHttpRequest()方法中开启了一个线程来发起 HTTP 请求,那么服务器响应的数据是无法进行返回的,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器还来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。
解决方法:Java 的回调机制
public interface HttpCallbackListener { //当服务器成功响应我们请求的时候调用 void onFinish(String response); //当进行网络操作出现错误的时候调用 void onError(Exception e); }
这两个方法都带有参数,onFinish()方法中的参数代表着服务器返回的数据,而 onError()方法中的参数记录着错误的详细信息。
改进版
public class HttpUtil {
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
if (listener != null) {
// 回调onFinish()方法
listener.onFinish(response.toString());
}
} catch (Exception e) {
if (listener != null) {
// 回调onError()方法
listener.onError(e);
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
}
//调用 HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(String response) { // 在这里根据返回内容执行具体的逻辑 } @Override public void onError(Exception e) { // 在这里对异常情况进行处理 } });
当服务器成功响应的时候我们就可以在 onFinish()方法里对响应数据进行处理了,类似地,如果出现了异常,就可以在 onError()方法里对异常情况进行处理。如此一来,我们就巧妙地利用回调机制将响应数据成功返回给调用方了。另外需要注意的是,onFinish()方法和 onError()方法最终还是在子线程中运行的,因此我们不可以在这里执行任何的 UI 操作。
二者区别
http://blog.csdn.net/hguang_zjh/article/details/33743249相关文章推荐
- Android网络相关(WiFi的开关,WiFi热点的开关,获取手机IP地址等)
- HttpResponseCode错误码整理
- 用JAVA实现网络数据包嗅探
- IP地址、NAT、子网划分与子网掩码、CIDR等网络层相关知识整理
- 关于梦行Monxin如何新增收银员
- 用C#实现实现简单的 Ping 的功能,用于测试网络是否已经联通
- Android网络应用(三)——网络数据解析
- Python即时网络爬虫:API说明
- 计算机网络学习笔记二
- HttpClient
- 项目部署之多项目war配置同一个Tomcat利用不同端口访问项目(省略项目名/projectName 直接http://localhost:8090/)
- WEB服务器、应用程序服务器、HTTP服务器区别
- [Protocol Analysis]Wireshark capture packet tcp udp checksum error
- 神经网络
- Android OkHttp完全解析 是时候来了解OkHttp了
- Socket Server-基于NIO的TCP服务器
- uri中为什么本地文件file后面跟三个斜杠, http等协议跟两个斜杠?
- HTTP协议详解
- 常见http状态
- html标记语言的标准写法-参考自http://www.zhihu.com/question/20797118/answer/16212312