Volley框架的基本解读
Posted zero-27
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Volley框架的基本解读相关的知识,希望对你有一定的参考价值。
在Volley框架的基本解读(一)中我们说了Volley与RequestQueue两个重要的类,说到了CacheDispatcher与NetworkDispatcher这两个调度类,比起缓存调度,我想大家可能会对网络调度更感兴趣,我们来看看:
public class NetworkDispatcher extends Thread
这个网络调度类本质是一个线程
public NetworkDispatcher(BlockingQueue<Request> queue,
Network network, Cache cache,
ResponseDelivery delivery)
mQueue = queue;
mNetwork = network;
mCache = cache;
mDelivery = delivery;
里面只有一个构造方法,从RequestQueue中传入的四个参数,分别是优先级队列,网络处理类,缓存处理类,结果分发类,回想一下,在RequestQueue的start方法中,NetworkDispatcher被创建后,便调用了NetworkDispatcher的start方法,因为它是一个线程,我们来看看run方法:
@Override
public void run()
// 设置最高线程优先级
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Request request;
while (true)
try
// Take a request from the queue.
request = mQueue.take();
catch (InterruptedException e)
// We may have been interrupted because it was time to quit.
// interrupt方法会尝试中断本线程,我们可能会被打断,因为这是该放弃的时候了
if (mQuit)
return;
continue;
try
// 调试标记:以成功取出队列中的request
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;
// Tag the request (if API >= 14)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
// 流量统计标记,配合DDMS工具统计流量使用情况
TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
// 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.
// 如果服务器返回无修改,并requset以完成分发,说明进行了重复的请求,移除该request
if (networkResponse.notModified && request.hasHadResponseDelivered())
request.finish("not-modified");
continue;
// Parse the response here on the worker thread.
// 交由Request进行解析Response
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)
parseAndDeliverNetworkError(request, volleyError);
catch (Exception e)
VolleyLog.e(e, "Unhandled exception %s", e.toString());
mDelivery.postError(request, new VolleyError(e));
看重点,mQueue是一个用于保存requset的网络优先级队列,我们在使用volley框架时,通过mQueue.add(stringRequest)该方法将request加入到RequestQueue中,而在RequestQueue中又将该request加入了PriorityBlockingQueue<Request>这样一个以优先级排序的队列中,也就是这里的mQueue。
上面源码我们可以看到,run方法中是一个while死循环,不断的试图从mQueue队列中取出request,try.....catch中的意义等会再说,然后就是各种判断,如果request标记取消,就结束这次网络请求,如果api大于14,进行流量统计,后面这句代码是重点:
// 前戏结束,这里就是真正的网络请求
NetworkResponse networkResponse = mNetwork.performRequest(request);
现在我们知道,NetworkDispatcher为什么是网络调度线程?因为它只负责将request传给mNetwork网络处理类,本身并不执行网络请求。
接着看,如果请求结果无修改并requset以完成分发,说明进行了重复的请求,结果无需返回。NetworkResponse是一个对返回结果封装的实体类,request对其进行解析,parseNetworkResponse该方法是一个抽象方法,request可以有很多具体实现子类,因此解析的方式只能由子类具体实现,如果需要缓存,将返回的数据加入缓存处理类中,最后由结果分发类调用postResponse(request, response)发起回调。
这里的内容有点多,可能有点乱,但多数是简单的判断,大家明白意义即可,具体的下面分析,在此之前我们再看两个方法:
/**
* 通知错误
*/
private void parseAndDeliverNetworkError(Request<?> request, VolleyError error)
error = request.parseNetworkError(error);
mDelivery.postError(request, error);
在上面的run方法中当catch捕捉到VolleyError异常,便会交给该方法处理,大概意思就是让request.parseNetworkError(error)解析这个错误,然后发起错误回调,值得一提的是parseNetworkError在request中是一个没有意义的方法,传进去的VolleyError会被原封不动的返回,但子类可以复写该方法,完成自己的错误解析。
/**
* Forces this dispatcher to quit immediately. If any requests are still in
* the queue, they are not guaranteed to be processed.
*
* 标记取消网络请求,并中断该线程
*/
public void quit()
mQuit = true;
interrupt();
这个方法大家看的是不是有点眼熟,它正是RequestQueue的stop方法中出现的,用于中断线程,代码很简单,改变了标记并调用了interrupt这个Thread中定义的尝试中断线程的方法,如果这个方法被调起,线程被中断会出现什么情况?大家想起了上面run方法中的try......catch了没,在catch中有这么一段代码:
// interrupt方法会尝试中断本线程,我们可能会被打断,因为这是该放弃的时候了
if (mQuit)
return;
continue;
interrupt方法会尝试中断本线程,while死循环即会抛出异常,mQuit为true,while循环被跳出,逻辑相当的精巧,有木有!
以上是关于Volley框架的基本解读的主要内容,如果未能解决你的问题,请参考以下文章