1、
其实缓存就是在下一次进行网络请求的时候,可以节省更多的时间,用于更快地展示数据。
那么是如何使用这个缓存功能的?
其实okhttp已经封装好了,如果要使用缓存的话,只需要在创建okhttpclient的时候,配置cache类就可以了。
在这个cache类中有两个参数,一个是File这个对象,它表示的是一个目录,还有一个是表示缓存目录大小的一个值,这样就设置好了你所需要的缓存路径。
2、
在cache类中有一个内部类internalCache
从代码可以看到,这是一个接口,这个接口中所有的方法,不管是put()、get(),它的实现都是通过cache这个类实现的。
3、首先看一下put()方法
在这个方法中,有一个非常重要的DiskLruCache。这个代码说明了什么?说明了整个okhttp的缓存,绕了这么大一个圈子,做了那么多封装,其实最终还是交给了DiskLruCache这个算法来实现的,这也说明了整个okhttp缓存的核心就是DiskLruCache这个缓存算法。但是okhttp对这个算法做了一些简单的改动。由于okhttp内部是维护了一个清理的线程池的,由这个清理的线程池实现对缓存的自动清理和管理工作。
4、
put()方法的具体实现
222行,其实就是得到一个请求的方法requestMethod,通过传入的参数response的rquest()请求,再调用它的method()方法来获取我们的requestMethod
224行,是对http请求的缓存是否有效进行判断,如果是有效的才会进行remove()操作
5、
232行,这一行非常关键,这是一个设置巧妙的所在。它不缓存非get方法的响应。意思是,如果不是get请求,比如是post请求,就没有必要缓存它的方法。
6、
243行,在创建好了它的方法,判断好了之后,走到了243行一个很重要的方法,new Entry()这个方法,entry这个实例就是要写入缓存的部分。
在创建好了Entry这个类以后,又创建了一个DiskLruCache.Editor这个对象,editor这个对象主要是用来写入的。
246行是创建真正的editor,通过cache.edit()这个方法。
cache顾名思义是DisLruCache,这也印证了刚才所说的,okhttp的缓存机制就是DiskLruCache,调用cache.edit()方法时传递了一个key值,然后就获取到了一个editor。这个key值,使用的是key()这个方法,这个方法是将网络请求的url转换成对应的key
250行,真正地开始缓存,调用的是entry的writeTo()方法。entry就是表示的我们需要写进缓存的那部分。它封装好了我们所需要的url、头部等等,然后调用的是writeTo()这个方法,这个方法就是将我们的缓存写道磁盘上,
注:
①Entry其实是一个static final类,它里面包含了许多像url、头部header、方法、协议protocol、code、message等等等等,其实okhttp就是把它所需要的所有属性都封装成了entry这个类,然后方便我们可以进行缓存,直接用这个包装类就可以进行缓存。
②key()方法的实现
其实就是将请求的url做md5加密处理,然后再得到md5的16进制表现形式
7、writeTo()方法
将缓存写到磁盘上。
缓存的信息主要包括url、请求方法、头部、对头部进行遍历,把头部的key和value全部缓存。这是第一步。
第二步,从623行开始,要缓存http的响应行statuline
635行要缓存响应的首部,responseHeaders
缓存好头部后会缓存比如时间、接收响应的时间等等
在642行会判断这个请求是不是https这个请求,然后才进行相应的握手以及整数信息的操作
writeTo()这个方法,当它写入缓存的时候,不仅仅是响应的头部信息,还包括请求的头部信息,包括url、请求方法、请求头部等等。
8、在put()方法中,writeTo()方法的参数是一个editor,在key值中只保存了url的md5值,那么有一个疑问,既然把请求的头部和响应的头部都缓存好了,最关键的请求主题body还保不保存?