Volley源码解析<五> CacheDispatcher和NetworkDispatcher
2016-02-24 09:15
344 查看
Volley源码解析<五> CacheDispatcher和NetworkDispatcher
@[Volley, 调度器, CacheDispatcher, NetworkDispatcher]声明:转载请注明出处,知识有限,如有错误,请多多交流指正!
Volley源码解析五 CacheDispatcher和NetworkDispatcher
结构
CacheDispatcher
NetworkDispatcher
结构
主要通过RequestQueue调用start()方法启动CacheDispatcher和NetworkDispatcher线程
CacheDispatcher
1. 构造方法CacheDispatcher继承自Thread,当被start后就执行它的run方法,在RequestQueue.add方法中,如果使用缓存直接就将Request放入缓存队列mCacheQueue中了,使用mCacheQueue的位置就是CacheDispatcher,CacheDispatcher的构造函数中传入了缓存队列mCacheQueue、网络队列mNetworkQueue、缓存对象mCache及结果派发器mDelivery
[code] public CacheDispatcher(BlockingQueue<Request<?>> cacheQueue, BlockingQueue<Request<?>> networkQueue, Cache cache, ResponseDelivery delivery) { mCacheQueue = cacheQueue; mNetworkQueue = networkQueue; mCache = cache; mDelivery = delivery; }
其中
cacheQueue:缓存请求队列,就是RequestQueue中的mCacheQueue
networkQueue:网络请求队列,就是RequestQueue中的mNetworkQueue
cache:保存缓存数据,就是RequestQueue中的mCache
delivery:用于分发响应结果,就是RequestQueue中的mDelivery
2. 主要运行方法run()
[code] public 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(); Request<?> request; while (true) { // release previous request object to avoid leaking request object when mQueue is drained. request = null; try { // Take a request from the queue. // 从缓存队列中取出请求 request = mCacheQueue.take(); } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } try { 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()); //缓存已过期(包括expired与Soft-expired) // 无缓存数据,则加入网络请求 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. // 缓存没有Soft-expired,则直接通过mDelivery将解析好的结果交付给请求发起者 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. final Request<?> finalRequest = request; //需要刷新,那么就再次提交网络请求...获取服务器的响应... mDelivery.postResponse(request, response, new Runnable() { @Override public void run() { try { // 网络来更新请求响应 mNetworkQueue.put(finalRequest); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (Exception e) { VolleyLog.e(e, "Unhandled exception %s", e.toString()); } } }
3. 其他
[code]//用于判断线程是否结束,用于退出线程 private volatile boolean mQuit = false; //出线程 public void quit() { mQuit = true; interrupt(); }
在run方法中一直运行着
while (true),那么是如何停止线程的呢?当通过调用
quit方法中
interrupt()时,会
InterruptedException异常退出线程
NetworkDispatcher
1. 构造方法原理和
CacheDispatcher基本上一样的,主要用于网络请求
[code] public NetworkDispatcher(BlockingQueue<Request<?>> queue, Network network, Cache cache, ResponseDelivery delivery) { mQueue = queue; mNetwork = network; mCache = cache; mDelivery = delivery; }
其中
queue:网络请求队列,就是RequestQueue中的mNetworkQueue
network:网络请求封装类,就是BasicNetwork
cache:保存缓存数据,就是RequestQueue中的mCache
delivery:用于分发响应结果,就是RequestQueue中的mDelivery
2. 主要运行方法run()
[code] public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Request<?> request; while (true) { long startTimeMs = SystemClock.elapsedRealtime(); // release previous request object to avoid leaking request object when mQueue is drained. request = null; try { // Take a request from the queue. request = mQueue.take(); } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } try { request.addMarker("network-queue-take"); // If the request was cancelled already, do not perform the // network request. // 如果请求被中途取消 if (request.isCanceled()) { request.finish("network-discard-cancelled"); continue; } // 流量统计用的 addTrafficStatsTag(request); // Perform the network request. // 请求数据 NetworkResponse networkResponse = mNetwork.performRequest(request); request.addMarker("network-http-complete"); // If the server returned 304 AND we delivered a response already, // we're done -- don't deliver a second identical response. if (networkResponse.notModified && request.hasHadResponseDelivered()) { //如果是相同的请求,那么服务器就返回一次响应 request.finish("not-modified"); continue; } // Parse the response here on the worker thread. // 解析响应数据 Response<?> response = request.parseNetworkResponse(networkResponse); request.addMarker("network-parse-complete"); // Write to cache if applicable. // 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"); } // Post the response back. //确认请求要被分发 request.markDelivered(); //发送请求 mDelivery.postResponse(request, response); } catch (VolleyError volleyError) { volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs); parseAndDeliverNetworkError(request, volleyError); } catch (Exception e) { VolleyLog.e(e, "Unhandled exception %s", e.toString()); VolleyError volleyError = new VolleyError(e); volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs); mDelivery.postError(request, volleyError); } } }
相关文章推荐
- kidd风的IOS日志之多线程(NSOperation)的介绍与使用
- JQuery EasyUI后台UI框架使用连载
- 16.1 redis基础概述
- UIDynamic物理引擎
- 今天已经算一下过来有一个礼拜了,还是感觉是在熬日子似的
- android include中的控件调用
- codeforces 609F. Frogs and mosquitoes 二分+线段树
- Calendar
- 没有销售员的阿里云
- Volley源码解析<四> RequestQueue请求队列
- iOS小明开发笔记(二十四) (NSCoding)
- 在机顶盒上控制网页焦点的方法
- 工具&符号
- 10款免费且开源的项目管理工具
- 升级Centos
- caffe中matlab接口配置
- mysql数据导出
- cocos 手游开发与 cocos-html5 页游的屏幕适配
- 关于docker学习资料整理
- 堆,优先队列以及堆排序