一句话概括:

OKHttp3通过拦截链的设计,让请求分成5个拦截器去处理,拦截器各司其职,扩展性非常高。拦截链是从自定义的拦截器开始,然后再到默认的5个拦截器。一般情况下我们想打印网络请求日志,所以可以自定义Log拦截器,如果要给所有请求添加Header,同样可以自定义Header拦截器。

5个默认拦截器的含义:

1.失败重试、重定向拦截器。
2.桥拦截器:主要是添加和删除一些header
3.缓存拦截器:根据缓存策略,如果缓存可用,直接返回缓存数据。
4.连接池拦截器:连接池会缓存http链接,连接池的好处是复用连接,少了3次握手,所以请求会更快
5.真正访问网络的拦截器:内部使用okio去发请求

OKIO:(超时、缓存机制)

  • Sink:类似java中输出流OutputStream
  • Source:类似java中的输入流InputStream
  • Buffer:看名字就知道就是一个缓冲区,看到这个Buffer 是不是想起了我们平时写io流时都会创建一个byte[] 作为缓存区,写入时,将这个缓存区的数据写入流,读取时,将流中的数据读入这个缓存区。往下看就会知道Buffer 的内部其实就是byte 数组。
  • ByteString:顾名思义,这个类跟byte 和 String 有关。
  • Segment 的实现方式是一个循环双线链表,当一个Segment 存满了,往链尾添加一个新的Segment 就又可以存储更多的数据了。**Buffer的写操作,实际上就是不断增加Segment的一个过程,读操作,就是不断消耗Segment中的数据。**是为了方便数据的转移。当一个Source 要读取一个Sink 中的数据时,其实就是把数据从Source 的Buffer 转移到Sink 的Buffer 中。此时如果Buffer 中是用byte[] 实现的,那么我们势必需要进行byte 数组拷贝的工作,但是用一个链表实现的情况下,我们可以直接把Sink 中的 Segment 节点的指针指到Source 中的Segment 链表尾就OK了,而不用进行数组拷贝,更高效。
  • 缓存机制主要通过SegmentPool来管理