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全解析:创建一个请求队列的主要内容,如果未能解决你的问题,请参考以下文章