sendRequest ()
上篇文章我们讲了sendRequest ()方法,这节接着来看readResponse方法:
|
|
定位到第8行:
writeRequestHeaders这个方法是HttpStream 接口的方法,由Http1xStream和Http2xStream重写。
如果采用http1.x协议,则执行Http1xStream里面的writeRequestHeaders方法,如果为http2.0,则执行Http2xStream的。由上文我们知道这取决于请求是http还是https。我们以1x为类:
首先得到请求的RequestLine(StatusLine),这个值由方法名、URL,Http协议拼接而成。
其次执行writeRequest方法:
|
|
主要是将StatusLine和header信息写入sink,sink是什么呢,因为从上篇我们知道OKhttp底部是socket通信,所以sink就相当于我们在httpUrlConnection中使用的inputStream,它是socket的写入流,而source就是OutPutStream。
readNetworkResponse()
再看第9行:
|
|
看下这个方法第7行是怎么组装的呢?
|
|
上面主要是对答复头部的信息进行整理,而readNetworkResponse方法的第13行主要是对服务返回的body进行组装整理:
|
|
|
|
这句代码最后执行到ChunkedSource (实现source接口)的 read方法:
|
|
上面我们已经分析了Source是我们从服务读取的输入流,类似于OutPutStream,read方法则是从服务读取。
最终,回到readResponse方法的第9行,我们得到了完整的networkResponse。
我们再来看看validate(cacheResponse, networkResponse)方法是如何判断缓存是否可用的:
|
|
cache response存在的情况下,应该是缓存过期或者强制放弃缓存,在此情况下,缓存策略全部交给服务器判断,客户端只用发送条件get请求来验证cache的内容是否有变更即可,如果缓存是有效的,则返回304 Not Modifiled,且response中不会包含body,否则cache改变,回复200, OK。response中包含body。条件get请求有两种方式一种是Last-Modified-Date,一种是 ETag。这里采用了Last-Modified-Date,通过缓存和网络请求响应中的Last-Modified来计算是否是最新数据,如果是则缓存有效。
回到第一篇文章查找两个个参数 forWebSocket 和 callerWritesRequestBody,可以发现,这两个参数都为false,那么就是说
在readResponse方法中默认是不会执行第8、9行的,而是会去执行第11行,我们分析过发送请求时使用的拦截器模式,这里对答复的操作也用了同样的方式,不同于请求调用的是intercept,这里用的是proceed。所以我们有必要再分析以下这个拦截器,
重点是 proceed方法:
|
|
里面的writeRequestHeader方法和 readNetworkResponse 方法我们已经分析过了。再经过这么多7788的跳转、嵌套,终于拿到了我们需要的Response。最后回到我们第一篇文章最初的getResponse 方法,找到这两句:
|
|
第一句很明显是得到我们的response,直接返回userResponse。
第二句是对请求结果发生重定向时的处理,client发送一个request之后,server可能回复一个重定向的response,并在这个response中告知client需要重新访问的server的IP。此时,client需要重新向新的server发送request,并等待新server的回复。所以我们需要单独判断重定向response,并发送多次request。有了OKHttp,这一切你都不用管,它会自动帮你完成所有这一切。OKHttp中followUpRequest()方法就是完成这个功能的。
总结
OKHttp底层源码还是相当复杂的,毕竟它的功能如此之强大。OKHttp默认采用了Keep-Alive持久连接技术(并不代表一定长连接,取决于服务器),可支持gzip编码的response。在cache的处理上,如果cache可用,则直接使用cache,否则使用网络数据。OKHttp会做cache过期的判断和过期后的再验证。有了OKHttp,这一切你都不用管,它帮你cover掉了!
当需要做用户验证和重定向时,我们一般需要发送认证request,或向新server发送request,也就是要重新再生成新request并发送出去。有了OKHttp,这一切你都不用管,它又帮你cover掉了!
后期
1、研读几遍更新其中的错误和不足的点。
2、完善流程图,做到全面理解。