Volley全解析(一):创建一个请求队列

在使用Volley进行网络请求,我们通常做法是:

RequestQueue requestQueue=Volley.newRequestQueue(context);

其实,在Volley类里面,有三个 重载的newRequestQueue方法。

  • newRequestQueue(Context context, HttpStack stack)
  • newRequestQueueInDisk(Context context, String dir, HttpStack stack)
  • newRequestQueue(Context context)
    通过重载的方法,我们可以传入自己的HttpStack来执行网络请求,HttpStack是网络请求的接口,实现者必须实现其方法。这也是Volley高扩展性的体现。我们还可以通过传入缓存地址,让Volley缓存到我们指定的位置。不论使用哪种方法,下面的代码是这些方法的关键代码:
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

代码首先判断当前Android设备的版本号,当版本号< 9采用HttpClient进行网络请求,否则采用HttpUrlConnection进行网络请求。其中,HttpClient在Android M开始被废弃,详情查看Android6.0的变化
至于为什么要采用这种方式处理,肯定是做兼容性处理,具体请点击此博客](http://android-developers.blogspot.com/2011/09/androids-http-clients.html)。
同时在程序的最后,调用了RequestQueue的start方法,让Volley开始进行工作。进入到start方法内部,其代码如下:

stop();  // Make sure any currently running dispatchers are stopped.
        // Create the cache dispatcher and start it.
        mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
        mCacheDispatcher.start();

        // Create network dispatchers (and corresponding threads) up to the pool size.
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }

在程序开始,先调用stop方法,让正在进行的请求关闭也就是说,每次调用start方法以后,之前未完成的网络请求都被停止。
接着,缓存线程启动,4个网络请求线程开始工作。至于为什么是4个,这是Volley的默认线程数,我们可以通过判断当前的网络状态来动态调整此时线程数。
首先,来看一下缓存线程的工作原理,通过mCacheDispatcher.start();进入到start方法内部,

            try {
                // Get a request from the cache triage queue, blocking until
                // at least one is available.
                final Request request = mCacheQueue.take();
                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());
                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.
                    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() {
                        @Override
                        public void run() {
                            try {
                                mNetworkQueue.put(request);
                            } catch (InterruptedException e) {
                                // Not much we can do about this.
                            }
                        }
                    });
                }

程序首先从缓存队列取出一个请求对象,如果此对象没有取消,就取出缓存,如果缓存为空,说明此请求对象没有被缓存下来,就将此请求对象放入到网络请求队列。如果不为空,继续做是否过期验证,如果没有过期,将缓存组合成响应对象送出去,如若过期,则将此请求对象放入网络请求队里,等待网络请求数据。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值