概述
本篇分析分析Volley如何生成请求,如何处理请求,以及请求如何返回。从分析中学习再做组件时如何处理请求。
生产者-消费者模型
生产者-消费者模型描述的是共享的缓冲区的两类线程,一类是添加消息的生产者,一类是处理消息的消费者。而基本涉及到的多线程处理的均使用这个模型。比如Glide,比如这边文档分析的Volley,比如OkHttp,再比如JDK中的ThreadPoolExecutor。
Volley的请求分发
启动线程
根据配置RequestQueue的start方法会启动相应的线程来分发处理请求。
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,CacheDispatcher用于处理是否请求命中缓存直接返回。一方面CacheDispatcher是消费者,处理mCacheQueue的请求。一方面CacheDispatcher是生产者,对于未命中缓存直接添加到mNetworkQueue中。
- 启动NetworkDispatcher,根据配置的线程数来启动网络请求的线程。NetworkDispatcher作为mNetworkQueue的消费者,不断从mNetworkQueue获取请求进行处理。
添加网络请求
client的代码通过RequestQueue的add方法添加请求,如果设置了不保留缓存,将直接的添加到mNetworkQueue中。如果设置了,添加到mNetworkQueue中。
public <T> Request<T> add(Request<T> 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;
}
mCacheQueue.add(request);
return request;
}
处理请求
缓存请求处理
在CacheDispatcher的run()方法中一直是循环处理请求。而在processRequest方法中
- 从缓存队列中或者请求
- 命中缓存直接返回
- 没有命中缓存直接添加到mNetworkQueue队列中。
可以自行分析processRequest方法查看逻辑。可以自行分析processRequest方法查看逻辑。
@Override
public void run() {
while (true) {
try {
processRequest();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
return;
}
}
}
}
网络请求处理
在NetworkDispatcher中与CacheDispatcher一样,一致循环处理请求。在mNetworkQueue中是从mNetworkQueue不断的获取请求进行网络请求。
可以自行分析processRequest方法查看逻辑。
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
try {
processRequest();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
return;
}
}
}
}
总结
这篇文章只是宽泛的讲解一下,Volley的网络请求的处理流程。并没有深入的去分析,比如处理请求部分只是说明一致循环处理请求,并没有说明队列里面内容为空了,线程会怎样,队列满了如何处理请求,这块设计到线程的设计。而本篇只是从结构上说明请求的处理。后面还会针对线程进行讲解。
- Volley对于请求的处理采用了生产者-消费者模型。
- 在做组件时,需要设计如何添加请求,添加到哪里,以及如何处理请求,这块是组件的脉络,而其他的设计是骨肉涉及更细节的结构。
- 从请求数据处理为出发,分析第三方开源库源码更容易一些。因为基本开源库的涉及到多线程的处理(多线程处理中又以生产者-消费者模型为经典)。
Over