热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android网络应用(二)——HttpURLConnection和HttpClient

HttpURLConnection获取HttpURLConnection实例对象请求方法一get请求方法二postHttpClient获取HttpClient抽象类GET请求创建一个

    • HttpURLConnection
      • 获取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


推荐阅读
author-avatar
小短腿Tel
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有