基于Android上网络请求的重要性,也基于volley的中等逻辑难度,闲着没事,又开始对它的原理研究了起来。
首先呈上最新的Volley类结构:
Volley
cacheDir=com.hai.cache
RequestQueue//请求队列
DiskBasedCache//硬盘缓存
cacheDir
BasicNetwork
HurlStack//httpUrlConnection请求
ExecutorDelivery(new Handler(Looper.getMainLooper()//执行回调Response的success和error
RequestQueue
AtomicInteger mSequenceGenerator
HashMap> mWaitingRequests
HashSet mCurrentRequests
PriorityBlockingQueue mCacheQueue
PriorityBlockingQueue mNetworkQueue
CacheDispatcher(request调度线程)
mCacheQueue
mNetworkQueue
mCache(DiskBasedCache)
mDelivery(ExecutorDelivery)
NetworkDispatcher[4] mDispatchers//4个网络分发线程
mNetworkQueue
mNetwork(BasicNetwork)
mCache(DiskBasedCache)
mDelivery(ExecutorDelivery)
如下是分析得出的volley运行过程:
1,mCache从缓存读取所有缓存文件的CacheHeader,记录缓存文件大小
2,CacheDispatcher循环从 mCacheQueue 中取走 request
判断request.isCanceled()?
是: mCurrentRequests.remove(request);判断request.shouldCache()
是: mCacheQueue 添加包含此request的queue;
否:判断DiskBasedCache是否有key为此请求的Uri的Cache.Entry?
否: mNetworkQueue 添加request:
是:判断Cache.Entry是否过期?
是:request.setCacheEntry(过期的entry), mNetworkQueue 添加request;
否:解析未过期的CacheEntry得到Response,再次判断需要刷新CacheEntry
是:request.setCacheEntry(过期的entry), mNetworkQueue.put(request);
否:mDelivery把结果传递到ui(Handler deliverResponse或者deliverError)
3,NetworkDispatcher循环从 mNetworkQueue 中取走request
BasicNetwork执行request
收集缓存Entry,为request设置headers.put("If-None-Match", entry.etag);
headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
HurlStack执行request,
connection.setUseCaches(false)
connection.设置additionalHeaders和request.getHeaders()
返回 BasicHttpResponse (包含headers和entity)
判断httpResponse的header是否==HttpStatus.SC_NOT_MODIFIED,
是:返回 NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
request.getCacheEntry().data, responseHeaders, true);
否:返回新的NetworkResponse
解析NetworkResponse得到 response
mCache存取request的response(responseheader和Content)
mDelivery把结果传递到ui(Handler deliverResponse或者deliverError)
如果我们写上这么一个demo:
void testVolley(){
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest request=new StringRequest(Request.Method.POST, "www.baidu.com", new Response.Listener() {
@Override
public void onResponse(String s) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
}
});
Request req = requestQueue.add(request);
req.toString();
}
当new StirngRequest的时候:会初始化这么些东西:
初始化一个StringRequest:
Request.Method.POST
Response.Listener
Response.ErrorListener
DefaultRetryPolicy
DEFAULT_TIMEOUT_MS = 2500;
DEFAULT_MAX_RETRIES = 1;
DEFAULT_BACKOFF_MULT = 1.0F;
mShouldCache=true
然后当requestQueue.add(request):
StringRequest 设置当前请求队列, mCurrentRequests 添加StringRequest
判断 request.shouldCache()?
否: mNetworkQueue.add(request);
是:mWaitingRequests是否包含cacheKey:
否: mWaitingRequests 添加key=uri,value=null, mCacheQueue 添加StringRequest
是: mWaitingRequests 添加key=uri,value=queue(包含request)
当添加requestQueue添加request完后,然后就是第一部分的volley运行过程了。
之所以我又更新了这篇博文,是因为volley对于网络请求的学习有着很好的借鉴意义,因此。。。,过段时间开始研究下试下流行的OkHttp。
附近是google官方volley源码包
http://download.csdn.net/download/u014763302/9263413