CacheDispatcher从缓存中获取数据

从上一篇文章我们已经知道,现在要处理的问题就是CacheDispatcher和NetworkDispatcher怎么分别去缓存和网络获取数据的问题,这两个问题我分开来讲。

但是首先说明的是,这两个问题其实是有联系的,当CacheDispatcher获取不到缓存的时候,会将request放入网络请求队列,从而让NetworkDispatcher去处理它;

而当NetworkDispatcher获得数据以后,又会将数据缓存,下次CacheDispatcher就可以从缓存中获得数据了。

这篇文章,就让我们先来了解volley是怎么从缓存中获取数据的。

第一个要说明的,当然是CacheDispatcher类,这个类本质是一个线程,作用就是根据request从缓存中获取数据

我们先来看它的构造方法

/**     * Creates a new cache triage dispatcher thread.  You must call {@link #start()}     * in order to begin processing.     * 创建一个调度线程     * @param cacheQueue Queue of incoming requests for triage      * @param networkQueue Queue to post requests that require network to      * @param cache Cache interface to use for resolution      * @param delivery Delivery interface to use for posting responses     */    public CacheDispatcher(            BlockingQueue<Request<?>> cacheQueue, BlockingQueue<Request<?>> networkQueue,            Cache cache, ResponseDelivery delivery) {        mCacheQueue = cacheQueue;//缓存请求队列        mNetworkQueue = networkQueue;//网络请求队列        mCache = cache;//缓存        mDelivery = delivery;//响应分发器    }从上面的方法看出,CacheDispatcher持有缓存队列cacheQueue,目的当然是为了从队列中获取东西。

而同时持有网络队列networkQueue,目的是为了在缓存请求失败后,将request放入网络队列中。

至于响应分发器delivery是成功请求缓存以后,将响应分发给对应请求的,分发器存在的目的我已经在前面的文章中说过几次了,就是为了灵活性和在主线程更新UI(至于怎么做到,我们以后会讲)

最后是一个缓存类cache,这个cache可以看成是缓存的代表,也就是说它就是缓存,是面向对象思想的体现,至于它是怎么实现的,等下会说明

看完构造方法,我们就直奔对Thread而言,最重要的run()方法

@Overridepublic void run() {if (DEBUG) VolleyLog.v("start new dispatcher");Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//设置线程优先级// Make a blocking call to initialize the cache.mCache.initialize();//初始化缓存对象while (true) {try {// Get a request from the cache triage queue, blocking until// at least one is available.// 从缓存队列中取出请求final Request<?> request = mCacheQueue.take();request.addMarker("cache-queue-take");// If the request has been canceled, don't bother dispatching it.if (request.isCanceled()) {//是否取消请求request.finish("cache-discard-canceled");continue;}// Attempt to retrieve this item from cache.Cache.Entry entry = mCache.get(request.getCacheKey());//获取缓存if (entry == null) {request.addMarker("cache-miss");// Cache miss; send off to the network dispatcher.mNetworkQueue.put(request);//如果没有缓存,放入网络请求队列continue;}// If it is completely expired, just send it to the network.if (entry.isExpired()) {//如果缓存超时request.addMarker("cache-hit-expired");request.setCacheEntry(entry);mNetworkQueue.put(request);continue;}// We have a cache hit; parse its data for delivery back to the request.request.addMarker("cache-hit");Response<?> response = request.parseNetworkResponse(//解析响应new NetworkResponse(entry.data, entry.responseHeaders));request.addMarker("cache-hit-parsed");if (!entry.refreshNeeded()) {//不需要更新缓存// Completely unexpired cache hit. Just deliver the response.mDelivery.postResponse(request, response);} else {// Soft-expired cache hit. We can deliver the cached response,// but we need to also send the request to the network for// refreshing.request.addMarker("cache-hit-refresh-needed");request.setCacheEntry(entry);// Mark the response as intermediate.response.intermediate = true;// Post the intermediate response back to the user and have// the delivery then forward the request along to the network.mDelivery.postResponse(request, response, new Runnable() {@Overridepublic void run() {try {mNetworkQueue.put(request);} catch (InterruptedException e) {// Not much we can do about this.}}});}} catch (InterruptedException e) {// We may have been interrupted because it was time to quit.if (mQuit) {return;}continue;}}}这个方法里面做了很多事情,我们按顺序看

1,,从缓存请求队列中取出request

2,判断这个request已经是否被取消,如果是,调用它的finish()方法,continue

3,否则,利用Cache获得缓存,获得缓存的依据是request.getCacheKey(),也就是request的url

4,如果缓存不存在,将request放入mNetworkQueue,continue

5,否则,检查缓存是否过期,是,同样将request放入mNetworkQueue,continue

6,否则,检查是否希望更新缓存,否,组装成response交给分发器mDelivery

7,否则组装成response交给分发器mDelivery,并且将request再加入mNetworkQueue,去网络请求更新

OK,上面的过程已经说得够清楚了。让人疑惑的很重要一步,就是Cache这个类到底是怎么获取缓存数据的,下面我们就来看看Cache这个类。

这个Cache其实是一个接口(面向抽象编程的思想),而它的具体实现,我们在第一篇文章的Volley类中看到,是DiskBasedCache类。

无论如何,我们先看接口

人生就像爬坡,要一步一步来。

CacheDispatcher从缓存中获取数据

相关文章:

你感兴趣的文章:

标签云: