一、Volley工作流程图:
继续从CacheDispatcher和NetworkDispatcher开始看起。
二、CacheDispatcher:
一个线程,用于调度处理走缓存的请求。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery
去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进入NetworkDispatcher
去调度处理。
(一)看源码前,先看一下从其成员变量与处理流程:
(1). 成员变量
BlockingQueue<Request<?>>
缓存请求队列
mCacheQueue
BlockingQueue<Request<?>> mNetworkQueue
网络请求队列
Cache mCache
缓存类,代表了一个可以获取请求结果,存储请求结果的缓存
ResponseDelivery mDelivery
请求结果传递类
(2). 处理流程图
(3)源码:
1、构造函数:一系列赋值初始化操作
/** * Creates a new cache triage dispatcher thread. You must call {@link #start()} * in order to begin processing. */ public CacheDispatcher(BlockingQueue<Request> cacheQueue, BlockingQueue<Request> networkQueue, Cache cache, ResponseDelivery delivery) { mCacheQueue = cacheQueue; mNetworkQueue = networkQueue; mCache = cache; mDelivery = delivery; }
提到使用CacheDispatcher时一定要调用start()方法;而CacheDispatcher的创建与线程start都是在RequestQueue中的add()函数中实现的:
// Create the cache dispatcher and start it. mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery); mCacheDispatcher.start();
2、既然是线程,重点看其run()函数:
@Override public void run() { //设置优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // Make a blocking call to initialize the cache. //这里的Cache其实是DiskBasedCache,见附I mCache.initialize(); /*****循环处理逻辑******/ while (true) { try { // 从缓存队列 mCacheQueue中取出一个Request;如果mCacheQueue为空,则阻塞进行忙等待 final Request request = mCacheQueue.take(); request.addMarker("cache-queue-take"); // 如果取出的Request请求已经被取消,则直接finish,处理下一个request if (request.isCanceled()) { request.finish("cache-discard-canceled"); continue; } // 尝试从缓存中获取request对应的结果 Cache.Entry entry = mCache.get(request.getCacheKey()); //为null,表示该cacheKey对应缓存结果不存在,则直接将request添加到mNetworkQueue中 if (entry == null) { request.addMarker("cache-miss"); mNetworkQueue.put(request); continue; } //如果缓存结果存在,但是已过期,同样也是将request添加到mNetworkQueue中 if (entry.isExpired()) { request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // 如果命中(hit)找到了对应的缓存结果,则解析其数据为Response并返回给该request request.addMarker("cache-hit"); Response<?> response = request.parseNetworkResponse( new NetworkResponse(entry.data, entry.responseHeaders)); request.addMarker("cache-hit-parsed"); // 还需判断缓存结果是否时间过久已经不新鲜,是否需要refresh if (!entry.refreshNeeded()) { // 不需要Refresh,则直接由mDelivery提交给相应的request mDelivery.postResponse(request, response); } else { // 如果已经不新鲜,mDelivery依旧提交结果给request, // 但同时要将Request传递给mNetworkQueue进行新鲜度验证 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) { } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } }
附I)这里的Cache实际是DiskBasedCache,mCache.initialize()实际上调用的是DiskBasedCache.initialize():
/** * Initializes the DiskBasedCache by scanning for all files currently in the * specified root directory. Creates the root directory if necessary. */ public synchronized void initialize()
三、NetworkDispatcher
一个线程,用于调度处理网络的请求。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给 ResponseDelivery 去执行后续处理,并判断结果是否要进行缓存。
(1). 成员变量
BlockingQueue<Request<?>>
网络请求队列
mQueue
Network mNetwork
网络类,代表了一个可以执行请求的网络
Cache mCache
缓存类,代表了一个可以获取请求结果,存储请求结果的缓存
ResponseDelivery mDelivery
请求结果传递类,可以传递请求的结果或者错误到调用者
(2). 处理流程图
(3).先看其构造函数,与CacheDispatcher的逻辑处理大致相同:
/** * Creates a new network dispatcher thread. You must call {@link #start()} * in order to begin processing. */ public NetworkDispatcher(BlockingQueue<Request> queue, Network network, Cache cache, ResponseDelivery delivery) { mQueue = queue; mNetwork = network; mCache = cache; mDelivery = delivery; }
(4).其run()函数:
@Override public void run() { //设为后台进程 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Request request; /*********循环处理逻辑********/ while (true) { try { // 从网络请求队列中取出request,同理mQueue为空时,也是忙等待 request = mQueue.take(); } catch (InterruptedException e) { if (mQuit) { return; } continue; } try { request.addMarker("network-queue-take"); // 如果取出的Request请求已经被取消,则直接finish,处理下一个request if (request.isCanceled()) { request.finish("network-discard-cancelled"); continue; } // Tag the request (if API >= 14) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { TrafficStats.setThreadStatsTag(request.getTrafficStatsTag()); } // 通过Network执行Request,获得NetworkResponse,故网络请求的处理逻辑应该都封装在了Network中 NetworkResponse networkResponse = mNetwork.performRequest(request); request.addMarker("network-http-complete"); // 用来验证新鲜度,(notModified=304)响应为304且请求已经有了Response传输情况 if (networkResponse.notModified && request.hasHadResponseDelivered()) { request.finish("not-modified"); continue; } // 将NetworkResponse解析为Response Response<?> response = request.parseNetworkResponse(networkResponse); request.addMarker("network-parse-complete"); // 如果request可以被缓存,并且其请求实体补位空,则添加到mCache中 // TODO: Only update cache metadata instead of entire record for 304s. if (request.shouldCache() && response.cacheEntry != null) { mCache.put(request.getCacheKey(), response.cacheEntry); request.addMarker("network-cache-written"); } // 传输Response request.markDelivered(); mDelivery.postResponse(request, response); } catch (VolleyError volleyError) { parseAndDeliverNetworkError(request, volleyError); } catch (Exception e) { VolleyLog.e(e, "Unhandled exception %s", e.toString()); mDelivery.postError(request, new VolleyError(e)); } } }