本文主要从两个入口进行分析:
一,Volley.newRequestQueue(context);
newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes)方法中:
A,请求队列requestQueue的初始化:
- 1. 根据当前手机版本创建网络协议
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);
- 2. 初始化请求队列 requestQueue
RequestQueue queue;
if (maxDiskCacheBytes <= -1)
{
// No maximum size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
}
else
{
// Disk cache size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
}
- 3. RequestQueue构造函数中接收 DiskBasedCache,network, 并进行如下初始化:
- 创建网络分发线程的数组
mDispatchers = new NetworkDispatcher[threadPoolSize]
默认数组大小为4; mDelivery = new ExecutorDelivery(new Handler(Looper.getMainLooper()))
,用于交付解析后的response , 需要通过在主线程中创建的handler对象
public RequestQueue(Cache cache, Network network, int threadPoolSize,
ResponseDelivery delivery) {
mCache = cache;
mNetwork = network;
mDispatchers = new NetworkDispatcher[threadPoolSize];
mDelivery = delivery;
}
- 4. 同时, requestQueue中会初始化两个成员变量: 缓存队列 和 网络队列
/** The cache triage queue. */
private final PriorityBlockingQueue<Request<?>> mCacheQueue =
new PriorityBlockingQueue<Request<?>>();
/** The queue of requests that are actually going out to the network. */
private final PriorityBlockingQueue<Request<?>> mNetworkQueue =
new PriorityBlockingQueue<Request<?>>();
B:执行 queue.start() 方法
/**
* Starts the dispatchers in this queue.
*/
public void 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();
}
}
-
1. 创建并开启mCacheDispatcher 子线程 run()方法中:
-
a,
mCache.initialize();
即DiskBasedCache中的方法,将cache目录下的volley目录中的所有文件遍历,读取每个文件的Header,封装到entry对象中,同时存入集合:
-
a,
File file = getFileForKey(key);
CountingInputStream cis = null;
try {
cis = new CountingInputStream(new BufferedInputStream(new FileInputStream(file)));
CacheHeader.readHeader(cis); // eat header
byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead));
return entry.toCacheEntry(data);
} catch (IOException e) {
VolleyLog.d("%s: %s", file.getAbsolutePath(), e.toString());
remove(key);
return null;
} catch (NegativeArraySizeException e) {
VolleyLog.d("%s: %s", file.getAbsolutePath(), e.toString());
remove(key);
return null;
} finally {
if (cis != null) {
try {
cis.close();
} catch (IOException ioe) {
return null;
}
}
}
- b,开启无限循环: 从mCacheQueue中获取request
while (true) {
...
request = mCacheQueue.take();
...
Cache.Entry entry = mCache.get(request.getCacheKey());
...
}
二,requestQueue.add(request);
主要是将requestt添加到mCacheQueue中:
mCacheQueue.add(request);
A, mCacheDispatcher
run()
方法中的无限循环会从mCacheQueue中获取到添加进去的request, 根据request.getCacheKey()
获取到mCache的集合变量中存储的entry对象
while (true) {
...
request = mCacheQueue.take();
...
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); //缓存数据中不存在,就将request添加到网络队列mNetworkQueue中,
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); //缓存数据过期,还是将request添加到mNetworkQueue中,
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");
...
mDelivery.postResponse(request, response); //交付给主线程处理解析后的响应结果
...
}
- 1.request.parseNetworkResponse 解析成功的返回结果:
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response))
-
2.
mDelivery.postResponse(request, response);
将解析出的响应结果交付到主线程处理
即执行:mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
传入的ResponseDeliveryRunnable的run()
方法:
// Deliver a normal response or error, depending.
if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}
即触发初始化Request时设置的监听器
B,NetworkDispatcher 的run()方法中的主要去执行真正的网络请求
NetworkResponse networkResponse = mNetwork.performRequest(request);
执行网络请求的主要有两个实现类:
- HurlStack的
performRequest()
方法:
URL parsedUrl = new URL(url);
HttpURLConnection connection = openConnection(parsedUrl, request);
HttpClientStackde performRequest方法:(适配9以下的API)
主要使用Apache的httpClient进行网络请求:
HttpPost postRequest = new HttpPost(request.getUrl());
- 1.将网络结果解析:
Response<?> response = request.parseNetworkResponse(networkResponse);
- 2.解析的结果存入缓存的集合中:
mCache.put(request.getCacheKey(), response.cacheEntry);
- 3.交付解析的结果:
mDelivery.postResponse(request, response);