文章目录
引言
上一篇文章我们简单的分析了HTTP 的协议,理解了HTTP协议的基本构成。在Android 6.0以前,Android 原生的HTTP请求方式有两种,HttpClient和HttpURLConnection。但因为HttpClient 的API比较复杂并且维护起来比较繁琐,Android 团队在6.0以后的版本便移除了HttpClient 的支持。而HttpUrlConnection由于其API 简单并且体积小便于维护,便成为了官方推荐的网络请求方式,我们这篇文章也主要讲述下HttpUrlConnection。
HttpUrlConnection 的使用
使用HttpUrlConnection 来进行网络请求大体上可以分为4个步骤:
- 获取到HttpURLConnection 对象
- 进行全局的网络设置并建立Http连接
- 进行数据处理
- 关闭连接
获取到HttpURLConnection 对象
使用URL 对象的openConnection()方法获取到HttpURLConnection 对象,这个对象是我们进行网络请求的核心。
网络请求在响应时间上有很大的不确定性,如果将网络请求放在主线程中执行,过长的耗时操作会阻塞主线程,导致程序卡死。因此,网络请求都应该放在子线程中执行。
示例代码如下
Url url = new URL("http://www.xianleshen:8080/springmvc/MyServlet/data?name=谦行&age=23");
connection = (HttpURLConnection) url.openConnection();
进行全局的网络设置并建立Http连接
获取到HttpURLConnection对象后,要进行一些网络设置,比如说设置网络请求方式,连接超时时间,读取超时时间,设置要发送的数据等。如以下代码所示:
// HttpURLConnection默认就是用GET发送请求,这里要发送数据,使用POST
connection.setRequestMethod("POST");
//设置连接超时时间
conn.setConnectTimeout(8000);
//设置读取超时时间
conn.setReadTimeout(8000);
// URL 连接可用于输入。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true
connection.setDoInput(true);
// URL 连接可用于输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。
connection.setDoOutput(true);
// 获取conn的输出流
OutputStream out = connection.getOutputStream();
//给这个输出流添加一个处理流,方便操作
DataOutputStream dos = new DataOutputStream(out);
//使用 writeBytes() 方法将数据提交到服务器
dos.writeBytes("username=admin&password=123456");
// 建立连接
connection.connect();
从服务器读取数据并进行数据处理
通过调用 HttpUrlConnection 对象的一些方法可以获取到服务器发送给客户端的相应信息,如状态码、响应内容长度、包含了响应内容的输入流等等。如以下示例代码:
//获取响应状态码,如 200 表示成功等
int responseCode = connection.getResponseCode();
//获取包含响应内容的输入流
InputStream in = connection.getInputStream();
//获取响应内容长度
int contentLength = connection.getContentLength();
在获取输入流之后,就可以利用 Java 中的 IO 流的知识对该输入流进行流处理,从而得到我们想要的数据。
关闭连接
在我们完成了所有数据写入和读取的流操作后,应该调用 disconnect() 方法关闭 Http 连接。
//关闭 Http 连接
connection.disconnect();
UrlHttpUtils
推荐给大家一个最简单的HttpURLconnection封装——UrlHttpUtils,只有五个Java文件,可以直接将java 文件拷到工程中使用。CallBack方法执行在UI线程。支持get请求,post请求,支持文件上传和下载。建议大家在有时间看看源码,这样才能灵活的使用这些封装的方法。
封装的功能
- 一般的get请求
- 一般的post请求
- 上传单个文件(包含进度)
- 上传list集合文件
- 上传map集合文件
- 文件下载(包含进度)
- 图片下载(实现了图片的压缩)
使用示例
GET请求
String url = "https://www.baidu.com/";
UrlHttpUtil.get(url, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
POST请求
String url = "https://www.baidu.com/";
HashMap<String, String> paramsMap = new HashMap<>();
paramsMap.put("title","title");
UrlHttpUtil.post(url, paramsMap, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
上传文件
File file = new File(Environment.getExternalStorageDirectory()+"/kwwl/abc.jpg");
HashMap<String, String> paramsMap = new HashMap<>();
paramsMap.put("title","title");
UrlHttpUtil.uploadFile("url", file, "image",UrlHttpUtil.FILE_TYPE_FILE, paramsMap, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
下载文件
UrlHttpUtil.downloadFile("url", new CallBackUtil.CallBackFile("fileDir","fileName") {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onProgress(float progress, long total) {
super.onProgress(progress, total);
}
@Override
public void onResponse(File response) {
}
});