目录
1、支持SPDY、HTTP2.0,共享同一个socket来处理同一个服务器的所有请求
1、如何使用OkHttp进行异步网络请求,并根据请求结果刷新UI
系列文章:
OKHttp开源框架学习三:任务调度核心类Dispatcher
OKHttp开源框架学习五:拦截器之RetryAndFollowUpInterceptor
OKHttp开源框架学习六:拦截器之BridgeInterceptor
OKHttp开源框架学习八:拦截器之CacheInterceptor
OKHttp开源框架学习九:拦截器之ConnectInterceptor
OKHttp开源框架学习十:ConnectionPool连接池
OKHttp开源框架学习十一:拦截器之CallServerInterceptor
相关文章:
一、Okhttp优势:
1、支持SPDY、HTTP2.0,共享同一个socket来处理同一个服务器的所有请求
2、如果SPDY不可用,则通过连接池来减少请求延时
3、无缝支持GZIP来减少数据流量
4、支持同步、异步(异步使用较多)
5、缓存响应数据来减少重复的网络请求
6、可以从很多常用的连接问题中自动恢复
下面我们进行逐条分析:
1、支持SPDY、HTTP2.0,共享同一个socket来处理同一个服务器的所有请求
支持SPDY、HTTP2.0
现在世界上的互联网协议有HTTP1.0、HTTP1.1、SPDY、HTTP2.0。
为什么支持SPDY、HTTP2.0显得这么重要,可以作为Okhttp的一个优点呢?
我们知道,目前使用最广泛的协议是HTTP1.1,但是其安全性不足、数据格式少。所以SPDY、HTTP2.0是一种趋势,会被越来越多地使用。
接下来我们简单聊一下互联网协议的历史。
在早期的互联网中,由于协议都是一些比较简单的协议,内容基本上都是一些静态的页面、图片等,所以无连接、无状态的HTTP可以发挥自己简单快速、灵活的优势。 但随着业务逻辑越来越复杂以及我们对安全性的重视,无连接、无状态反而成为了HTTP的劣势,所以也就又来后来更加高级的互联网协议的诞生。
第一个要讲的就是SPDY,这是谷歌开发的一种互联网协议。它是一种HTTP的兼容协议、支持多路复用请求、对请求划分优先级(优先返回文字,图片音频等随后返回)、压缩HTTP头,以减少请求数据量。
而HTTP2.0是在SPDY的基础上开发而来的,那么既然有了SPDY,为什么还要开发HTTP2.0。这是因为SPDY是完全由谷歌公司开发,这么重要的网络协议被把持在一家公司手里显然是不合适的。所以IETF(国际互联网工程任务组 The Internet Engineering Task Force,简称 IETF)就重新开发了HTTP2.0。HTTP2.0在SPDY的基础上又添加了更安全的SSL协议。
SPDY和HTTP2.0作为一种更高级的网络协议,Okhttp必须得支持才行啊。而像其他的框架volley暂时是不支持HTTP/2的。所以这可以作为它的一个优点!
共享同一个socket来处理同一个服务器的所有请求
此问题暂时找不到相关资料。
OkHttp3的最底层是Socket,而不是URLConnection,它通过Platform的Class.forName()反射获得当前Runtime使用的socket库
socket发起网络请求的流程一般是:
(1). 创建socket对象;
(2). 连接到目标网络;
(3). 进行输入输出流操作。
(1)(2)的实现,封装在connection接口中,具体的实现类是RealConnection。
(3)是通过stream接口来实现,根据不同的网络协议,有Http1xStream和Http2xStream两个实现类
由于创建网络连接的时间较久(如果是HTTP的话,需要进行三次握手),而请求经常是频繁的碎片化的,所以为了提高网络连接的效率,OKHttp3实现了网络连接复用
2、如果SPDY不可用,则通过连接池来减少请求延时
那么okhttp是怎么通过连接池来减少请求延时呢?
可以参考 OKHttp开源框架学习十:ConnectionPoll连接池
3、无缝支持GZIP来减少数据流量
为什么叫无缝支持的,意思就是说,你发送的数据和接受的收据在传递过程中都是经过gzip压缩的,并且这基本上你不需要你手动处理的,框架自动会帮你处理好。
相关文章:OkHttp使用gzip时的坑
这一点我们可以看BridgeIntercept的intercept方法:
//通过request传递数据时使用了gzip
boolean transparentGzip = false;
if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {
transparentGzip = true;
requestBuilder.header("Accept-Encoding", "gzip");
}
//接受服务器返回的数据response时也使用了gzip
if (transparentGzip
&& "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))
&& HttpHeaders.hasBody(networkResponse)) {
GzipSource responseBody = new GzipSource(networkResponse.body().source());
Headers strippedHeaders = networkResponse.headers().newBuilder()
.removeAll("Content-Encoding")
.removeAll("Content-Length")
.build();
responseBuilder.headers(strippedHeaders);
String contentType = networkResponse.header("Content-Type");
responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
}
4、支持同步、异步(异步使用较多)
这个很简单,没什么可说的。
5、缓存响应数据来减少重复的网络请求
OKHttp开源框架学习八:拦截器之CacheInterceptor
6、可以从很多常用的连接问题中自动恢复
OKHttp开源框架学习五:拦截器之RetryAndFollowUpInterceptor
二、Okhttp的核心类有哪些?简单讲一下
Dispatcher类:OKHttp开源框架学习三:任务调度核心类Dispatcher
Interceptor类:OKHttp开源框架学习四:拦截器
三、OkHttp方面的其他面试题
1、如何使用OkHttp进行异步网络请求,并根据请求结果刷新UI
第一步,创建一个OkHttpClient对象
第二步,创建携带请求信息的Request对象
第三步,创建Call对象
Request request = new Request.Builder().url("http://www.baidu.com").get().build();
Call call = mClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
LogUtils.json(response.body().string());
runOnUiThread(new Runnable() {
@Override
public void run() {
tvShow.setText("eeeeee");
}
});
}
});
需要注意的是,不能直接在Callback中更新UI,否则会报出异常:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original
thread that created a view hierarchy can touch its views.
可以在runOnUiThread方法中更新UI。
2、可否介绍一下OkHttp的整个异步请求流程
3、OkHttp对于网络请求都有哪些优化,如何实现的
- 通过连接池来减少请求延时
- 无缝支持GZIP来减少数据流量
- 缓存响应数据来减少重复的网络请求
- 可以从很多常用的连接问题中自动恢复
4、OkHttp框架中都用到了哪些设计模式
相关文章:OkHttp3源码解析--设计模式
- 构造者模式;
- 工厂模式;
- 观察者模式;
- 单例模式;
- 策略模式;
- 责任链模式;
- 享元模式;