Android网络请求开源库Android知识Android技术知识

Volley 核心源码解析(二)

2017-05-08  本文已影响16人  秋兰兮青青

请求队列 RequestQueue

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

public Request add(Request request) {

// Tag the request as belonging to this queue and add it to the set of current requests.

request.setRequestQueue(this);

synchronized (mCurrentRequests) {

mCurrentRequests.add(request);

}

// Process requests in the order they are added.

request.setSequence(getSequenceNumber());

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

// If the request is uncacheable, skip the cache queue and go straight to the network.

if (!request.shouldCache()) {

mNetworkQueue.add(request);

return request;

}

// Insert request into stage if there's already a request with the same cache key in flight.

synchronized (mWaitingRequests) {

String cacheKey = request.getCacheKey();

if (mWaitingRequests.containsKey(cacheKey)) {

// There is already a request in flight. Queue up.

Queue> stagedRequests = mWaitingRequests.get(cacheKey);

if (stagedRequests == null) {

stagedRequests = new LinkedList>();

}

stagedRequests.add(request);

mWaitingRequests.put(cacheKey, stagedRequests);

if (VolleyLog.DEBUG) {

VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);

}

} else {

// Insert 'null' queue for this cacheKey, indicating there is now a request in

// flight.

mWaitingRequests.put(cacheKey, null);

mCacheQueue.add(request);

}

return request;

}

}

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

那么这两个是什么呢?

/**

* The set of all requests currently being processed by this RequestQueue. A Request

* will be in this set if it is waiting in any queue or currently being processed by

* any dispatcher.

*/

private final Set> mCurrentRequests = new HashSet>();

/**

* Staging area for requests that already have a duplicate request in flight.

*

*

*    

containsKey(cacheKey) indicates that there is a request in flight for the given cache

*          key.

*    

get(cacheKey) returns waiting requests for the given cache key. The in flight request

*          isnotcontained in that list. Is null if no requests are staged.

*

*/

private final Map>> mWaitingRequests =

new HashMap>>();

看英文注释意思:

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

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

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

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

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

request.setSequence(getSequenceNumber());

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

接下来如下:

if (!request.shouldCache()) {

mNetworkQueue.add(request);

return request;

}

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

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

mNetworkQueue  的定义如下:

/** The queue of requests that are actually going out to the network. */

private final PriorityBlockingQueue> mNetworkQueue =

new PriorityBlockingQueue>();

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

在Request 类中 我们看到

private boolean mShouldCache = true;

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

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

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

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

mCacheQueue:

private final PriorityBlockingQueue> mCacheQueue =

new PriorityBlockingQueue>();

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

上一篇下一篇

猜你喜欢

热点阅读