一、HttpClient:
HttpClient本人用的比较少,然后进行了一些了解,主要有以下几个方面:
- HttpClient是Apache的一个第三方网络框架,对网络请求封装的比较完善,有众多的api,比较稳定。
- 扩展性不强,android5.0被废弃,6.0逐渐删除。
- 创建HttpClient对象,对于get请求,再创建HttpGet对象,对于post请求,再创建HttpPost对象。
- 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
- 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
- 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
二、HttpURLConnection
- HttpURLConnection比较轻量级,对网络请求的封装没有HttpClient完善,用起来也没有那么方便。
- HttpURLConnection对象不能直接构造,需要通过URL类中的openConnection()方法来获得。
- 对HttpURLConnection对象的配置需要在connect方法执行之前完成。
- HttpURLConnection是基于HTTP协议的,底层通过socket通信实现,需要设置请求方式和超时。
- HttpURLConnection通过getInputStream()返回一个输入流,从中获取服务器对于HTTP请求的返回信息。对于post请求方式,需要通过getOutputStream()流写入,写入到缓冲区中。
- 由于HttpURLConnection调用 close() 函数会影响连接池,导致连接复用失效,若使用需要关闭keepAlive,极大的不方便,每次HTTP请求都有。
- HttpUrlConnection现在的底层实现是通过Okhttp
//开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.connect();
//如果是Post方式时
// String params = "abc";
// OutputStream out = connection.getOutputStream();
// out.write(params.getBytes());
// out.flush();
// out.close();
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);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
//将服务器返回的结果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
// showResponse(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(connection != null){
connection.disconnect();
}
}
}
}).start();
三、Volley
- Volley适合处理数据量小,通信频繁的网络操作;在处理大数据量的请求时,表现不好,因为在内部使用的是字节数组缓存池ByteArrayPool(维护了两个List集合),每次从缓冲区取空间,不必每次存数据都进行内存分配,减少GC。
- Volley内部封装了异步线程,可直接在主线程请求网络并处理返回的结果。
- 容易扩展,支持HttpClient、HttpURLConnection、甚至OkHttp,也封装了ImageLoader。
- Volley可以取消请求。
- 一个缓存线程,4个网络线程。
关于Volley的详细使用,可以去看我的另一篇文章:最简单详细的Volley使用解析。
四、okhttp
- 谷歌官方在6.0以后移除了httpClient,加入了okhttp
- okhttp是专注于提升网络连接效率的http客户端,支持连接同一地址的链接重用同一个socket,避免了每次都创建socket再断开socket,通过连接池来减小响应延迟。
- okhttp支持SPDY(是谷歌开发的基于TCP的应用层协议,用于最小化网络延迟,提升网络速度,优化用户的网络使用体验. SPDY并不是一种替代http的协议,只是对http的一种增强)。
- okhttp支持http和https,支持连接池、GZIP和HTTP缓存。
- 成熟的网络请求解决方案,比HttpURLConnection更好用。
- OkHttp基于NIO和Okio,在性能上也就更快。
- 缺点是okhttp请求网络切换回来是在线程里面的,不是在主线程,不能直接刷新UI,需要我们手动处理。封装比较麻烦。
okhttp发起网络请求:
- 构建 OkHttpClient 客户端
- 构建 Request 请求
- 创建 Call 对象,发起网络请求
- 处理 Response 响应结果
使用:同步get请求
new Thread(new Runnable() {
@Override
public void run() {
try {
//构建okHttp客户端
OkHttpClient client = new OkHttpClient();
//构建请求报文
Request request = new Request.Builder().url("https://www.baidu.com").build();
//发起同步请求,返回响应报文
Response response = client.newCall(request).execute();
//获取响应体
String responseData = response.body().string();
showResponse(responseData);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
异步get请求
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS).build();
final Request request = new Request.Builder().url("https://www.baidu.com").get().build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("MainActivity",e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("MainActivity",Thread.currentThread().getName());
//运行在子线程中,所以必须在主线程中更改UI
showResponse(response.body().string());
}
});
番外篇:
- Retrofit也是Square公司开发的,默认基于OkHttp封装的一套RESTful网络请求框架,可以使用不同的http客户端,同时支持RxJava,目前使用比较多的是Retrofit+OkHttp+RxJava+Dagger2。
- 对于Retrofit和OkHttp来说,肯定首选Retrofit,因为Retrofit默认就是基于OkHttp进行的封装。
- IO(阻塞式IO) 和 NIO(非阻塞式)的区别:如果从硬盘读取数据,IO就是程序会一直等,数据读完后才能继续操作;NIO是你读你的数据,程序接着往下执行,等数据处理完你再来通知我,然后再处理回调。 所以NIO当然要比IO的性能要好了。而 Okio是 Square 公司基于IO和NIO基础上做的一个更简单、高效处理数据流的一个库。
- Retrofit2.0优化了很多地方,相比较Volley来说,Retrofit默认OkHttp,再结合RxJava的话,Retrofit应该更好一点。当然一般简单项目可以使用Volley。
- RxVolley是基于Volley框架现在又比较流行的框架。RxVolley=Volley+RxJava+OkHttp。怎么说呢,这个框架用起来还是很不错的,不过我的了解现在还不够深入,等着熟悉了之后再更新RxVolley的详细使用。