Android中的volley_8_缓存调度线程CacheDispatcher

CacheDispatcher也是volley的核心类之一。

跟NetworkDispatcher一样,CacheDispatcher也是一个线程,该线程的作用就是从缓存队列中获取request,根据request的cacheKey从缓存Cache内获取该request的响应。在RequestQueue内,会对所有的request进行分发,如果一个request是可以被缓存的,那么就会分发到缓存队列中。需要注意的是,在volley中只会创建一个缓存调度线程,而会创建默认的四个网络调度线程。

重要的成员变量:

/** The queue of requests coming in for triage. 缓存请求队列,缓存调度线程会一直从该队列中取请求*/
	private final BlockingQueue<Request> mCacheQueue;

	/** The queue of requests going out to the network. 网络请求队列*/
	private final BlockingQueue<Request> mNetworkQueue;

	/** The cache to read from. 缓存*/
	private final Cache mCache;

	/** For posting responses. 响应传递机制*/
	private final ResponseDelivery mDelivery;

工作流程:

1.在构造方法内会传入这四个成员变量,缓存调度线程是在RequestQueue的start()方法内创建并启动的,一start就开始执行线程的run方法。

public CacheDispatcher(BlockingQueue<Request> cacheQueue,
			BlockingQueue<Request> networkQueue, Cache cache,
			ResponseDelivery delivery) {
		mCacheQueue = cacheQueue;
		mNetworkQueue = networkQueue;
		mCache = cache;
		mDelivery = delivery;
	}

2.在run方法内,首先初始化缓存操作    mCache.initialize();   主要是如果没有缓存目录就创建缓存目录,如果缓存目录已经存在就读取缓存。

3.由于缓存调度线程会一直存在,因此在run内部是用while(true)来括起来的,通网络调度线程是一样的。

4.先从缓存队列中读取request,如果缓存队列为空,那么阻塞在这里,一直等待。

// Get a request from the cache triage queue, blocking until
// at least one is available.从缓存请求队列中取出一个请求,这是一个阻塞的方法,当缓存请求队列中没有请求时会一直等待,直到取到一个请求
    final Request request = mCacheQueue.take();

5.从缓存队列中获取到request后

// 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;
				}

6.接下来是从request内获取响应数据

// 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() {
						@Override
						public void run() {
							try {
								mNetworkQueue.put(request);
							} catch (InterruptedException e) {
								// Not much we can do about this.
							}
						}
					});
				}

缓存调度线程就是这些了。


demo下载:http://download.csdn.net/detail/vvzhouruifeng/8747599

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值