虽说volley已经好多年了,最近打算开始写一些博客,就从最开始用过的框架开始些吧。
这一篇只是简单写一下volley网络请求的过程,下一篇打算写写volley 的cache机制
先放一张volley的官方运行流程图,讲述了volley中一个request的执行过程,可以看到,volley主要分成了三种线程,分别是
主线程
cache线程
网络线程(包含多个线程)
下面看一次网络请求流程
1 构建一个RequestQueue
2 构造一个Request
3 RequestQueue.add(Request)
4 RequestQueue.start() //该方法不一定非要添加request后再执行
这样就很清晰了,先看一下RequestQueue的add方法
/**
* Adds a Request to the dispatch queue.
*
* @param request The request to service
* @return The passed-in request
*/
public Request add(Request request) {
// Tag the request as belonging to this queue and add it to the set of current requests.
request.T(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;
}
mCacheQueue.add(request);
return request;
}
把 Request 添加到当前的请求集合中
给这个请求设置序列号
判断是否需要cache,
不需要直接加入网络请求队列,返回
需要cache将请求添加到cache队列中
继续看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();
}
}
可以看出这里新创建了一个CacheDispatcher,和若干个NetworkDispatcher,然后调用start方法。
实际上,他们就是新创建的几个线程,这样一来就能跟最上面的整体架构图对上了,一个cache线程,多个网络请求线程(默认4个)
NetworkDispatcher 与 CacheDispatcher 继承自Thread
下面看一下CacheDispatcher的主要方法
@Override
public void run() {
if (DEBUG) VolleyLog.v("start new dispatcher");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
// Make a blocking call to initialize the cache.
mCache.initialize();
while (true) {
try {
// Process request if cache not hit, add it to mNetworkQueue
processRequest();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
Thread.currentThread().interrupt();
return;
}
VolleyLog.e(
"Ignoring spurious interrupt of CacheDispatcher thread; "
+ "use quit() to terminate it");
}
}
}
private void processRequest() throws InterruptedException {
// Get a request from the cache triage queue, blocking until
// at least one is available.
final Request> request = mCacheQueue.take();
processRequest(request);
}
总结一下就是CacheDispatcher这个线程不断轮询,取出当前需要处理的请求进行处理,如果cache不能够命中或者已经过期需要刷新就将这个request添加到NetworkDispatcher中进行处理
NetworkDispatcher默认是4个
和CacheDispatcher的run方法一样NetworkDispatcher也是不断循环,取出当前队列中的request进行处理,这里主要看一下如何返回请求的
void processRequest(Request> request) {
long startTimeMs = SystemClock.elapsedRealtime();
try {
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");
request.notifyListenerResponseNotUsable();
return;
}
addTrafficStatsTag(request);
// 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.
if (networkResponse.notModified && request.hasHadResponseDelivered()) {
request.finish("not-modified");
request.notifyListenerResponseNotUsable();
return;
}
// Parse the response here on the worker thread.
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);
request.notifyListenerResponseReceived(response);
} catch (VolleyError volleyError) {
volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
parseAndDeliverNetworkError(request, volleyError);
request.notifyListenerResponseNotUsable();
} catch (Exception e) {
VolleyLog.e(e, "Unhandled exception %s", e.toString());
VolleyError volleyError = new VolleyError(e);
volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
mDelivery.postError(request, volleyError);
request.notifyListenerResponseNotUsable();
}
}
可以看出这段代码关键的地方有两处,一处是发送网络请求返回结果,一处是mDelivery.postResponse将结果返回
在主线程执行
总体结构