RequestQueue:
RequestQueue的创建:
Volley.newRequestQueue
RequestQueue 初始化之前会初始化下面几个容器
/** Used for generating monotonically-increasing sequence numbers for requests. */
private AtomicInteger mSequenceGenerator = new AtomicInteger();
/**
* 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
* is not contained in that list. Is null if no requests are staged.
*
*/
private final Map>> mWaitingRequests =
new HashMap>>();
/**
* 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>();
/** The cache triage queue. */
private final PriorityBlockingQueue> mCacheQueue =
new PriorityBlockingQueue>();
/** The queue of requests that are actually going out to the network. */
private final PriorityBlockingQueue> mNetworkQueue =
new PriorityBlockingQueue>();
private List mFinishedListeners =
new ArrayList();
紧接着就是构造函数
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
if (stack == null) {
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();
return queue;
}
这里我们只讨论Android sdk 9(Android 2.3) 以上的版本,并且用户没有自定 HttpStack 的情况.
在这里我们看到 newRequestQueue里创建了 4个对象,分别是:
- File cacheDir.
- HurlStack stack:
public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
mUrlRewriter = urlRewriter;// urlRewriter ==null
mSslSocketFactory = sslSocketFactory; // sslSocketFactory ==null
}
通过源码得知,创建 HurlStack 并未做任何其他操作,只是创建了一个对象而已
- BasicNetwork network.
public BasicNetwork(HttpStack httpStack) {
/** If a pool isn't passed in, then build a small default pool that will give us a lot of */
/** 翻译:如果没有传入池,那么构建一个小的默认池,它将为我们提供很多 */
/** benefit and not use too much memory */
/** 翻译:受益,而不是使用太多的记忆 */
this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));
/** DEFAULT_POOL_SIZE == 4096 */
}
这里创建 BasicNetwork 时,创建了一个 ByteArrayPool 对象, ByteArrayPool 创建时,创建了一个 LinkedList,以及 一个 ArrayList 用于实现缓存,这里创建的 ArrayList 预初始化长度 为 64,也就是说这里有了一点内存开销.
- RequestQueue queue.
public RequestQueue(Cache cache, Network network, int threadPoolSize,
ResponseDelivery delivery) {
/** DiskBasedCache */
mCache = cache;
/** BasicNetwork */
mNetwork = network;
/** threadPoolSize = 4*/
mDispatchers = new NetworkDispatcher[threadPoolSize];
/** new ExecutorDelivery(new Handler(Looper.getMainLooper()) */
mDelivery = delivery;
}
这里新建了一些对象:
DiskBasedCache:
产生了一些实现缓存的内存开销.
ResponseDelivery:
1. Handler
1. Executor 这里的Executor 用于执行线程转换,将其他工作线程的执行结果 发送到主线程执行,没什么特殊处理或操作,它的主要代码执行片段如下:
private class ResponseDeliveryRunnable implements Runnable {
private final Request mRequest;
private final Response mResponse;
private final Runnable mRunnable;
public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
mRequest = request;
mResponse = response;
mRunnable = runnable;
}
@SuppressWarnings("unchecked")
@Override
public void run() {
// If this request has canceled, finish it and don't deliver.
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}
// Deliver a normal response or error, depending.
if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}
// If this is an intermediate response, add a marker, otherwise we're done
// and the request can be finished.
if (mResponse.intermediate) {
mRequest.addMarker("intermediate-response");
} else {
mRequest.finish("done");
}
// If we have been provided a post-delivery runnable, run it.
if (mRunnable != null) {
mRunnable.run();
}
}
}
NetworkDispatcher:
1.创建了4个 Thread 对象(仅仅是创建对象,目前尚未产生线程开销),产生线程开销的时机可能在后面的业务执行时.
RequestQueue 对象创建好了之后,会立即执行 start函数,每次调用 start函数都会重新创建 一个CacheDispatcher,该对象是一个Volley自定义的线程对象,并且会马上调用该线程start函数,产生了一次线程创建开销(个人对线程开销的理解是,如果仅仅是new Thread 而不调用start 函数,那么他只是一个普通的对象,一旦调用了 start 函数,那么就产生了一些列的线程开销,就java而言,新建一个线程的开销的是很大的,当然我的观点是就线程开销而言,并没有说是Volley的作者这么写有问题,Volley的这种实现方式是基于它的需求驱动的结果,如果我们可以使用线程池完成业务实现,还是使用线程池实现比较好.).
RequestQueue 对象的创建部分就告一段落了,接下来就是 RequestQueue的各个函数实现