1,Volley是实现了磁盘缓存机制的,它会自动缓存http的返回头表明可以缓存的数据(和图片)。
2,如果我们使用的图片服务器没有设置这个缓存头,该如何去修改?
关键类:ImageRequest.java NetworkDisPather.java ImageLoader.java NetworkImageView.java RequestQueue.java
Volley.java会在newRequestQueue()方法中启动RequestQueue
继续追:发现启动了两个Dispatcher,拦截器,分别用来处理缓存请求和网络请求
追到NetworkDispatcher中的run()方法(上面为啥是start()方法?呵呵)
上图的方法太长,只截了关键代码
看TODO中说明了,如果request设置了shouldCache(true)并且 response.cacheEntry不为空,才将返回数据(图片)进行缓存。
1,shouldCache————由request自行设置
2,response.cacheEntry不为空,在上图第一个箭头处,继续追代码看 request.pastNetworkResponse是如何实现的。
request是抽象类,我们直接看ImageRequest的实现:
追doParse:太长只贴了关键代码:
success方法:
嗯,cacheEntry是有HttpHeaderParse获得的,查看方法:
方法说明已经说清楚了,如果cache-control中允许缓存就缓存,否则为空。
大部分图片( CDN)一般都会带允许缓存,在返回头中是这样的:
而动态信息一般是max-age=0 或者是no-cache
到此为止,我们分析的是通常情况下的缓存情况,下面我们来看图片该怎么处理
request必需设置shouldCache+图片必需自带缓存头:
如果我们使用ImageRequest,自己手动设置就行了,或者你修改一下这个类重新这个方法。但是在NetworkImageView中,我们根本没用ImageRequest,该怎么办呢,那就要分析ImageLoader代码了:
这是我们常用的方法:
发现对请求进行了封装,封装到 ImageContainer中,追iamgeloader的get 方法:
很简单,这里才是生产request的位置,我手动加一个shouldcache就行了。
哈哈,依然用的是ImageRequest!
现在解决了第一个问题———必需设置shouldCache
我们开始解决第二个问题:如何“手动”让图片拥有缓存头:
Volley中判断缓存头的位置在HttpHeaderParse的parseCacheHeaders方法,我们不想修改原来的代码,就添加一个相同的方法进行重载,添加两个参数:
代码也copy一份下来,我们只修改一下逻辑代码:原来返回的是Null。
另一个位置:找不到位置的按行号来:
现在我们就完成了这里的修改,那现在进入到刚才ImageRequest的调用位置进行修改:
在ImageRequest中添加一个变量来控制是否进行强制缓存,再添加一个变量来控制缓存时间:
在使用中,只需要设置一下forceCache就行了:
这是我们之间使用ImageRequest,那么如果使用的是NetworkImageView呢?
上面我们已经分析过NetworkImageView的逻辑了,直接在同一位置修改刚才的ImageRequest:
由于ImageLoader一般是唯一的,所以这里打开了,所有用ImageLoader的就全部打开了强制缓存,慎用。
技术有限,如有出入,望指正。 :)