Volley 核心源码解析(二)

淡蓝 2016-03-08

请求队列RequestQueue

每一个使用过Volley的同行们都用过RequestQueue.add(request)这个方法,看看这个方法到底做了什么:

public<T>Request<T>add(Request<T>request){

//Tagtherequestasbelongingtothisqueueandaddittothesetofcurrentrequests.

request.setRequestQueue(this);

synchronized(mCurrentRequests){

mCurrentRequests.add(request);

}

//Processrequestsintheordertheyareadded.

request.setSequence(getSequenceNumber());

request.addMarker("add-to-queue");

//Iftherequestisuncacheable,skipthecachequeueandgostraighttothenetwork.

if(!request.shouldCache()){

mNetworkQueue.add(request);

returnrequest;

}

//Insertrequestintostageifthere'salreadyarequestwiththesamecachekeyinflight.

synchronized(mWaitingRequests){

StringcacheKey=request.getCacheKey();

if(mWaitingRequests.containsKey(cacheKey)){

//Thereisalreadyarequestinflight.Queueup.

Queue<Request<?>>stagedRequests=mWaitingRequests.get(cacheKey);

if(stagedRequests==null){

stagedRequests=newLinkedList<Request<?>>();

}

stagedRequests.add(request);

mWaitingRequests.put(cacheKey,stagedRequests);

if(VolleyLog.DEBUG){

VolleyLog.v("RequestforcacheKey=%sisinflight,puttingonhold.",cacheKey);

}

}else{

//Insert'null'queueforthiscacheKey,indicatingthereisnowarequestin

//flight.

mWaitingRequests.put(cacheKey,null);

mCacheQueue.add(request);

}

returnrequest;

}

}

我们看到这里面有两个被用synchronized块锁住的对象:mCurrentRequests,mWaitingRequests

那么这两个是什么呢?

/**

*ThesetofallrequestscurrentlybeingprocessedbythisRequestQueue.ARequest

*willbeinthissetifitiswaitinginanyqueueorcurrentlybeingprocessedby

*anydispatcher.

*/

privatefinalSet<Request<?>>mCurrentRequests=newHashSet<Request<?>>();

/**

*Stagingareaforrequeststhatalreadyhaveaduplicaterequestinflight.

*

*

*<li>containsKey(cacheKey)indicatesthatthereisarequestinflightforthegivencache

*key.</li>

*<li>get(cacheKey)returnswaitingrequestsforthegivencachekey.Theinflightrequest

*isnotcontainedinthatlist.Isnullifnorequestsarestaged.</li>

*

*/

privatefinalMap<String,Queue<Request<?>>>mWaitingRequests=

newHashMap<String,Queue<Request<?>>>();

看英文注释意思:

mCurrentRequests大意是,当前在这个队列里所有正在被执行的请求的集合。所有的正在被执行的或者在队列中等待执行的请求都应该放进这个set集合中。

mWaitingRequests:包含重复请求的临时区域,

通俗的说就是一个是所有正在执行和等待执行的请求集合,另一个是存放重复请求的临时区域是一个map.

当我们调用add方法的时候首先是把请求加入到mCurrentRequests中,当然咯,这个过程是同步的。

此时volley还给每个请求设置了序号和备注:

request.setSequence(getSequenceNumber());

request.addMarker("add-to-queue");

接下来如下:

if(!request.shouldCache()){

mNetworkQueue.add(request);

returnrequest;

}

这段代码很有意思,如果一个请求不支持被缓存的话,马上就把这个请求交给mNetworkQueue

中去执行,后面的代码不再执行。

mNetworkQueue的定义如下:

/**Thequeueofrequeststhatareactuallygoingouttothenetwork.*/

privatefinalPriorityBlockingQueue<Request<?>>mNetworkQueue=

newPriorityBlockingQueue<Request<?>>();

这是一个全新的阻塞式的队列。这个队列的作用后面再讲。

在Request类中我们看到

privatebooleanmShouldCache=true;

说明Volley中默认每一个请求都是要被缓存的。

接下来通过Request的cacheKey区分请求是否重复,如果有重复请求,就把这个请求所属的队列拿出来,然后把新的请求加到队列中,再存到mWaitingRequests中。

如果mWaitingRequests中没有这个请求,就用这个请求的cacheKey去保存一个NULL值,

言简意赅的说;每一个请求都会在执行的同时放到mWaitingRequests中,同时也要被放进缓存队列中,

mCacheQueue:

privatefinalPriorityBlockingQueue<Request<?>>mCacheQueue=

newPriorityBlockingQueue<Request<?>>();

mCacheQueue中的请求何时执行,后面会讲到。

下一节Volley的任务调度模型http://f303153041.iteye.com/blog/2281352

相关推荐