Volley源码学习(三):线程处理request,类CacheDispatcher,NetworkDispatcher,ExecutorDelivery

一.源码解析

volley处理request的流程:当调用RequestQueue的add(request)方法时,会进行一系列逻辑判断:如先从cache获取,没有或者过期,再从网络获取。这是通过将request添加到CacheQueue和NetworkQueue里,最终是由线程类CacheDispatcher,NetworkDispatcher进行相应处理的。

1.类CacheDispather,缓存请求处理线程类,在RequestQueue的start方法里启动
线程类,一直循环读取request,如果cache里没有或过期,然后添加request到networkQueue里从网络获取→有,将cacheentry变成networkresponse,并用request解析成response→不需更新就直接用mDelivery.postResponse(request, response);,需更新就之后再从网络获取
   public CacheDispatcher(
            BlockingQueue<Request> cacheQueue, BlockingQueue<Request> networkQueue,
            Cache cache, ResponseDelivery delivery) {
        mCacheQueue = cacheQueue;      //读取request,进行cache的操作
        mNetworkQueue = networkQueue;    //将request add到networkqueue里进行网络请求
        mCache = cache;            //cache缓存,这里使用DiskBasedCache(cacheDir),将文件缓存到本地
        mDelivery = delivery;      //用于将respone发送给request里的listener的方法
    }
    @Override
    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();    //缓存初始化

        while (true) {
            try {
                // Get a request from the cache triage queue, blocking until
                // at least one is available.
                final Request request = mCacheQueue.take();       //从CacheQueue里获得request,没有就阻塞
                request.addMarker("cache-queue-take");

                // If the request has been canceled, don't bother dispatching it.
                if (request.isCanceled()) {           //如果request被取消,就finish
                    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()) {           //cache过期,去网络请求   
                    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(       //调用request方法解析networkResponse为response
                        new NetworkResponse(entry.data, entry.responseHeaders)); <span style="font-family: Arial, Helvetica, sans-serif;">//将cacheentry变成networkResponse</span>
                request.addMarker("cache-hit-parsed");

                if (!entry.refreshNeeded()) {                 //不需要更新就自己delivery response到对应request的listener
                    // 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() {     //postResponse后再从网络更新Cache
                        @Override
                        public void run() {
                            try {
                                mNetworkQueue.put(request);
                            } catch (InterruptedException e) {
                                // Not much we can do about this.
                            }
                        }
                    });
                }

            } catch (InterruptedException e) {
                // We may have been interrupted because it was time to quit.
                if (mQuit) {
                    return;
                }
                continue;
            }
        }
    }

2.类NetworkDispatcher,线程处理网络请求
从queue里获取request→先判定是否取消,然后finish(request)→网络请求response = request.parseNetworkResponse(networkResponse);→
response = request.parseNetworkResponse(networkResponse);解析成response→需要缓存就调用mCache的put方法→mDelivery.postResponse(request, response);发送结果→异常时发送错误
    public NetworkDispatcher(BlockingQueue<Request> queue,
            Network network, Cache cache,
            ResponseDelivery delivery) {
        mQueue = queue;
        mNetwork = network;
        mCache = cache;
        mDelivery = delivery;
    }<pre name="code" class="html">    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        Request request;
        while (true) {
            try {
                // Take a request from the queue.
                request = mQueue.take();     //获取request,没有就阻塞
            } 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
                    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());
                }

                // Perform the network request.
                NetworkResponse networkResponse = mNetwork.performRequest(request);       //获得networkResponse
                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()) {           //如果没修改且已经发送repsonse,结束request
                    request.finish("not-modified");
                    continue;
                }

                // Parse the response here on the worker thread.
                Response<?> response = request.parseNetworkResponse(networkResponse);    //解析成response
                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);                   //将response结果post到requst的listener里,实际转接
            } catch (VolleyError volleyError) {
                parseAndDeliverNetworkError(request, volleyError);       //异常时发送错误
            } catch (Exception e) {
                VolleyLog.e(e, "Unhandled exception %s", e.toString());
                mDelivery.postError(request, new VolleyError(e));
            }
        }
    }
 
 

3.类ExecutorDelivery,用于发送response或error到request的listener
使用主线程的looper来处理线程。调用postResponse方法时处理一次线程,将response和error传给requset
    public ExecutorDelivery(final Handler handler) {   //handler使用主线程Looper.getMainLooper()
        // Make an Executor that just wraps the handler.
        mResponsePoster = new Executor() {
            @Override
            public void execute(Runnable command) {
                handler.post(command);
            }
        };
    }    @Override
    public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
        request.markDelivered();
        request.addMarker("post-response");
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
    }<pre name="code" class="html">    @Override
    public void postError(Request<?> request, VolleyError error) {
        request.addMarker("post-error");
        Response<?> response = Response.error(error);
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
    }
    @SuppressWarnings("rawtypes")
    private class ResponseDeliveryRunnable implements Runnable {
        private final Request mRequest;
        private final Response mResponse;
        private final Runnable mRunnable;

        public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
            mRequest = request;
            mResponse = response;
            mRunnable = runnable;
        }

        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            // If this request has canceled, finish it and don't deliver.
            if (mRequest.isCanceled()) {      //取消就结束
                mRequest.finish("canceled-at-delivery");
                return;
            }

            // Deliver a normal response or error, depending.
            if (mResponse.isSuccess()) {             //成功就调用request的方法,获得reponse.data
                mRequest.deliverResponse(mResponse.result);
            } else {
                mRequest.deliverError(mResponse.error);       //失败,就调用request的方法获得response.error
            }

            // If this is an intermediate response, add a marker, otherwise we're done
            // and the request can be finished.
            if (mResponse.intermediate) {
                mRequest.addMarker("intermediate-response");
            } else {
                mRequest.finish("done");
            }

            // If we have been provided a post-delivery runnable, run it.
            if (mRunnable != null) {
                mRunnable.run();
            }
       }
    }


 
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值