一、什么是OkHttp3
(1)定义:
OkHttp3是一个处理网络请求的开源项目,是目前最火的网络框架,作者是Square公司,
用于代替Android提供的HttpConnection和HttpClient。**
(2)OkHttp的特点
1、是基于建造者模式(将一个复杂对象的构建与它的表示分离,用于属性参数很多 时。)创建的
建造者模式:https://www.jianshu.com/p/be290ccea05a
2、链式调用,每一个方法的返回值类型都是当前类的对象
(3)它的优点是什么
支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。)
socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,减少了请求延迟,
共享Socket,减少对服务器的请求次数。
拥有Interceptors轻松处理请求与响应(自动处理GZip压缩)。
二、OKHttp的功能
PUT,DELETE,POST,GET等请求
文件的上传下载
加载图片(内部会图片大小自动压缩)
支持请求回调,直接返回对象、对象集合
支持session的保持
OkHttp请求流程
使用 OkHttp 发起一个请求主要三步:
1、需要构造一个 OkHttpClient
2、构造请求信息 Request
3、发起请求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://www.baidu.com")
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
System.out.println("成功");
}
} catch (IOException e) {
e.printStackTrace();
}
发起一个请求整体流程:
首先当OkHttpClient对象想要发送一个网络请求的时会执行newCall()方法这是我们将Request放在这个方法里边,
之后通过返回的okhttp的对象去去调用newCall方法
我们是从newCall开始的在源码中newCall会给我们返回个RealCall,newRealCall();
在RealCall中会将我们传进来的request传给我们的OrigginalRequest对象
(OrigginalRequest之后会在getresponseIntecepterchain里的拦截链RealInterceptorChain()调用)
接下来如果我们是去进行一个同步请求的话也就是在代码当中调用excute()方法
进入excute()方法之后首先会先调用client。dispatcher()。excute(this);
这个方法的目的是通知调节器dispatcher我现在要开始执行任务了然后调用了getresponseInterceptorchain()方法
在这个方法执行结束以后会给我们返回一个通过http请求获取的request对象
最后会调用client。dispatcher。finish()来通知调度器dispatcher我现在任务执行结束了你可以让其他的认为来执行了
然后我们来说说它具体的执行过程,具体的执行过程是·在getresponseInterceptorchain()中执行的
**在这个方法里有一个泛型是interceptor也就是拦截器的集合在这个结合里存入了5个拦截器
之后创建了一个拦截链RealInt**erceptorChain();通过我们拦截链获取的对象去调用process()方法
这个也就是我们所说的链式调用
在这个方法中有一个索引值index每次我们去调用这个process方法的时候他都会加1**
然**后我们会根据这个索引值去判断我们去调用哪个拦截器当我们第一次调用这个方法的时候index为1回去调用我们集合当中
的第一个拦截器当拦截器执行完毕之后会去创建一个新的拦截链并且通过这个新的拦截链去再次调用process方法
然后去执行下一个拦截器
一直到所有的拦截器都调用完毕它会给我们返回一个的Request对象
而这个过程就是一个递归;
那么它是如何去判断我们已经调用到最后一个拦截器了那?
它是通过索引值index当index>集合的长度的时候那么它就会结束这个方法了因为我们index是从1开始的
所以需要index值大于集合长度的时候
我们集合里的拦截器才会全部执行完毕
然后我们去说一说这5个拦截器都是什么分别有什么作用
(五大拦截器)
一、RetryAndFollowUpInterceptor (重定向拦截器)
RetryAndFollowUpInterceptor 的拦截操作中做了这么几件事:
1、创建一个 StreamAllocation
2、发起请求
3、请求异常时会重试
4、根据响应码做重定向和重试
5、重定向时如果地址不一致会释放连接
6、另外也保存是否取消的状态值,在重试、请求得到响应后都会判断是否取消
二、BridgeInterceptor (桥接拦截器)
内置的拦截器中第二个是 BridgeInterceptor。Bridge,桥,什么桥?连接用户请求信息 和 HTTP 请求的桥梁。
BridgeInterceptor 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应。
我们说下侨界拦截器大概都做了什么吧,请求前:
1、如果这个请求有请求体,就添加 Content-Type, Content-Length 等
2、如果这个请求没有 Host,就通过 url 来获取 Host 值添加到 Header 中
3、如果这个请求没有接收的数据类型Accept-Encoding,且没指定接收的数据范围,就添加默认接受格式为 gzip
5、去 CookieJar 中根据 url 查询 Cookie 添加到 Header
6、如果当前没有,就添加 User-Agent 信息
发起请求后:
7、解析响应 Header 中的 Cookie
8、如果想要数据的格式是 gzip,就创建 GzipSource 进行解压,同时移除 Content-Encoding 和 Content-Length
三、CacheInterceptor (缓存拦截器)
第三个拦截器是缓存处理拦截器 CacheInterceptor,它的重要性用一句话来描述:最快的请求就是不请求,直接用缓存。
首先,根据request来判断cache中是否有缓存的response,如果有,得到这个response,然后进行判断当前response是否有效,
没有将cacheCandate赋值为空。
根据request判断缓存的策略,是否要使用了网络,缓存 或两者都使用
调用下一个拦截器,决定从网络上来得到response
如果本地已经存在cacheResponse,那么让它和网络得到的networkResponse做比较,决定是否来更新缓存的cacheResponse
缓存未经缓存过的response
、