1、
okhttp的缓存都是由CacheInterceptor缓存拦截器来完成的。
53行调用的是cache的get()方法,就是说会尝试去获取缓存。有两种结果,一种是获取到缓存对象,另一种是没有获取到缓存对象。
57行是获取时间戳。
59行是获取到了一个新的对象CacheStrategy。是通过工厂类CacheStrategy.Factory().get()的get()方法来获取缓存策略的。
然后根据cachestrategy对象获取它内部维护的request和response对象,为下面进行缓存拦截器的操作打下铺垫。
63行会根据缓存是否为null,如果不为空的话会调用缓存中的trackResponse()方法。这个方法的主要作用是,当有缓存的情况下,它会更新一下相应的统计指标,主要是缓存的命中率。
67行主要调用了closeQuietly()这个方法。这个方法其实就是当这个缓存不符合要求的话,就将它关掉。和io流的处理是一样的。
72行,如果当前是不能使用网络的,又没有找到相应的缓存,这时会通过构建者模式构建一个Response,并抛出一个504的错误
85行判断有缓存,又不能使用网络的时候,直接将缓存的结果返回。
93行通过拦截器获取网络请求的获取,里面的工作还会交给下一个拦截器。下一个拦截器就是connection拦截器。
通过拦截器链的拦截工作后,通过网络来获取网络的response。这里首先判断响应码是否是HTTP_NOT_MODIFIED(304),如果是代表我们需要从缓存中获取。就是说接下来的操作都是从缓存中去读取数据。
131行,首先会判断Http头部有没有响应体并且缓存策略是可以被缓存的,如果满足条件就会将网络响应保存到缓存当中,这样下次去取的时候就可以直接从缓存中读取数据返回。
135行判断这个request是否是一个无效的缓存方法,如果是的话则从缓存池中删除这个缓存。
其实这个cacheinterceptor和网络协议比较贴近。
2、
CacheStartegy内部维护了一个请求Request networkRequest和一个响应Response cacheResponse,内部可以通过描述是通过request 网络还是通过response缓存还获取数据,或者还可以两者同时使用,既使用网络又使用缓存。
3、CacheStrategy工厂类的get()方法
它也是空壳,它的具体实现在getCanidate()方法中
4、getCandidate()
实际创建CacheStrategy()的类
186行,会对缓存的response进行判断断,如果cacheResponse==null说明缓存中没有这个对象,那么就直接建一个CacheStrategy请求,传入request对象,response没有,第二个参数为null
191行这个判断主要是用来判断这个请求是否是httpps的,以及这个请求中是否已经经过handshake()握手操作,如果都满足条件的话会重新进行网络请求。
198行主要用来判断这个响应该不该被存储,会根据okhttp的一个准则。如果它不该被存储,则应该重新地去进行网络请求。
203行,如果缓存中指定了不使用响应,调用的是noCache()方法,或者是hasConditions()可选择的一个http请求,如果满足其中一个,就会重新进行网络请求
208行对缓存进行判断,.immutable()意思是是否是不容易被影响的。做的操作主要是,因为responseCaching是不被影响的,是可以调用response的,所以此时传入的参数request为null,而response为cacheResponse
230行,前面是对一些request、response的一些判断,这里是比较缓存的response,检查它是否有请求的一些头部,比如添加warning等,主要是添加请求头的一些操作。
238返回请求对象CacheStrategy,传入的参数是通过构建者来做的。
5、trackResponse()方法
这个是在接口中,没有具体的实现,
首行注释说明,应用不应该去实现它,而应该去实现okhttp3.cache
找到该方法。这是一个synchronized同步方法,每次调用时都会rquestCount++,接下来判断cacheStrategy.networkRequest是否为空,如果不为空,networkCount++。
下面判断cacheStrategy.cacheResponse是否不为空,如果不为空的话hitCount++,这一步是最重要的一步,如果走到这里,说明命中了这个缓存。
6、
7、