Volley简单学习使用四——源码分析二

一、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));
            }
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值