本文代码省略了许多个人认为不重要的内容,具体请参考volley源码
volley的入口在Volley.java的newRequestQueue方法中
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;
}
上面的代码最主要的内容是在SDK>9的时候使用HttpUrlconnection,其他时候使用HttpClient(BTW: 据说HttpClient在android6.0上已经不能使用了)
最重要的代码是queue.start()
queue.start(); //初始化,开始接收网络请求
mCacheDispatcher.start();
mCache.initialize(); //缓存初始化
while(true)
if (request.isCanceled()) { //请求是否取消
request.finish("cache-discard-canceled"); //执行finish
}
Cache.Entry entry = mCache.get(request.getCacheKey()); //尝试从缓存中获取
if (entry == null) {
mNetworkQueue.put(request); //如果缓存中没有,添加到网络队列
}
if (entry.isExpired()) { //检查缓存是否过期
request.setCacheEntry(entry); //缓存已经过期,重用缓存实例,将缓存加入到网络队列中
mNetworkQueue.put(request);
}
//此时缓存已经命中,根据volley支持的几种网络请求(图片,json,string等)解析网络应答
Response> response = request.parseNetworkResponse(
new NetworkResponse(entry.data, entry.responseHeaders));
if (!entry.refreshNeeded()) { //根据httpHeader中的softTtl判断缓存是否需要刷新
//分配器交付此次网络应答
mDelivery.postResponse(request, response);
} else {
//根据softTtl设置来说,缓存已经过期,依旧可以交付此次网络应答,不过需要后台刷新此次请求
request.setCacheEntry(entry);
response.intermediate = true;
mDelivery.postResponse(request, response, new Runnable() { //此次网络应答已经过期,虽然可以交付,但是需要进行刷新操作
@Override
public void run() {
mNetworkQueue.put(request);
}
});
}
networkDispatcher.start();
while (true)
request = mQueue.take();
if (request.isCanceled()) { //请求已经取消
request.finish("network-discard-cancelled");
}
addTrafficStatsTag(request); //统计流量使用
NetworkResponse networkResponse = mNetwork.performRequest(request); //执行网络请求
while (true)
Map responseHeaders = Collections.emptyMap(); //httpHeader
Map headers = new HashMap(); //cacheHeader
httpResponse = mHttpStack.performRequest(request, headers); //网络请求核心部分,httpstack需要实现performRequest用于请求http应答
int statusCode = statusLine.getStatusCode(); //获取网络状态码
responseHeaders = convertHeaders(httpResponse.getAllHeaders()); //获取httpHeader
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
entry.responseHeaders.putAll(responseHeaders); //更新缓存的httpHeader
return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, entry.data, //返回网络应答
entry.responseHeaders, true,
SystemClock.elapsedRealtime() - requestStart);
}
//处理部分网络entity为空的情况
if (httpResponse.getEntity() != null) {
responseContents = entityToBytes(httpResponse.getEntity());
} else {
responseContents = new byte[0];
}
//处理部分网络速度过慢问题
logSlowRequests(requestLifetime, request, responseContents, statusLine);
if (statusCode < 200 || statusCode > 299) { //在ioException中处理网络异常情况
throw new IOException();
}
return new NetworkResponse(statusCode, responseContents, responseHeaders, false, //返回网络应答
SystemClock.elapsedRealtime() - requestStart);
if (networkResponse.notModified && request.hasHadResponseDelivered()) { //返回304或者网络请求已经被处理
request.finish("not-modified");
}
Response> response = request.parseNetworkResponse(networkResponse); //解析网络应答
if (request.shouldCache() && response.cacheEntry != null) { //缓存网络应答
mCache.put(request.getCacheKey(), response.cacheEntry);
}
request.markDelivered(); //标记请求已经被处理
mDelivery.postResponse(request, response); //分配器交付此次网络应答
在start方法中默认创建了一个缓存线程和四个网络线程,分别对应着一个缓存队列一个网络队列,缓存线程和网络线程不停的从这两个队列中获取request并执行,那么这两个队列中的request从何而来的呢,答案是queue.add
queue.add();
mCurrentRequests.add(request); //将请求添加到请求队列中,用于在cancel中取消
if (!request.shouldCache()) { //如果不需要缓存直接加入网络队列中,否则加入缓存队列
mNetworkQueue.add(request);
return request;
}
if (mWaitingRequests.containsKey(cacheKey)) { //如果等待队列中包含缓存的key,更新请求
Queue> stagedRequests = mWaitingRequests.get(cacheKey);
stagedRequests.add(request);
mWaitingRequests.put(cacheKey, stagedRequests);
} else {
mWaitingRequests.put(cacheKey, null);
mCacheQueue.add(request);
}
从add方法中可以看出除非request设置了不需要缓存,默认都会将request添加到缓存队列中去,然后由mCacheDispatcher来做下一步的处理
未完待续。。。