您的位置:首页 > 其它

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);
            }
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: