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

Posted 袁阳的csdn博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.
                            
                        
                    );
                

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

以上是关于Volley全解析:创建一个请求队列的主要内容,如果未能解决你的问题,请参考以下文章

Volley源码解析

volley2--volley的使用和架构

Volley 解析

Volley源码分析面向接口编程的典范

volley

Volley