Volley源码阅读
1:初始化
RequestQueue = Volley.newRequestQueue(context)初始化请求队列。
初始化请求队列步骤如下
在volley的newRequestQueue函数中首先设置缓存的路径(只有硬盘缓存);之后初始化网络的连接方式,代码如下
if(stack == null) {
if(VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
即当手机版本的SDK大于9时采用HurlStack否则采用HttpClientStack,就是当SDK大于9时采用HttpURLConnection进行网络通讯否则采用HttpClient。
之后再初始化网络请求处理的具体类BasicNetwork,BasicNetwork实现了Network的performRequest方法,用来处理具体的网络请求。
BasicNetwork network1 = new BasicNetwork((HttpStack)stack);
RequestQueue queue1 = new RequestQueue(new DiskBasedCache(cacheDir), network1);
queue1.start();
这样RequestQueue就算初始化了。
2:接着看看RequestQueue的start()方法的具体实现
public void start() {
this.stop();
this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);
this.mCacheDispatcher.start();
for(int i = 0; i < this.mDispatchers.length; ++i) {
NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery);
this.mDispatchers[i] = networkDispatcher;
networkDispatcher.start();
}
}
看代码可知在start过程中其实就是调用mCacheDispatcher.start()和networkDispatcher.start();而这两个类其实就是继承自thread的线程类,所以在
RequestQueue的start()方法中就是先启动一个缓存线程,然后根据RequestQueue中线程池的大小启动了线程池大小数目的网路线程,在volley中默认的线程池大小是4,所以在start()方法中一共启动了5个线程。而start()方法中的第一句stop就是如果RequestQueue中有缓存线程或者网络线程的话将这些线程退出。
3:mCacheDispatcher.start()方法的具体实现
既然是线程,所以看看run()方法就行了。
while(true) {
final Request e = (Request)this.mCacheQueue.take();
e.addMarker(“cache-queue-take”);
if(e.isCanceled()) {
e.finish(“cache-discard-canceled”);
} else {
Entry entry = this.mCache.get(e.getCacheKey());
if(entry == null) {
e.addMarker(“cache-miss”);
this.mNetworkQueue.put(e);
} else if(entry.isExpired()) {
e.addMarker(“cache-hit-expired”);
e.setCacheEntry(entry);
this.mNetworkQueue.put(e);
} else {
e.addMarker(“cache-hit”);
Response response = e.parseNetworkResponse(new NetworkResponse(entry.data, entry.responseHeaders));
e.addMarker(“cache-hit-parsed”);
if(entry.refreshNeeded()) {
e.addMarker(“cache-hit-refresh-needed”);
e.setCacheEntry(entry);
response.intermediate = true;
this.mDelivery.postResponse(e, response, new Runnable() {
public void run() {
try {
CacheDispatcher.this.mNetworkQueue.put(e);
} catch (InterruptedException var2) {
;
}
}
});
} else {
this.mDelivery.postResponse(e, response);
}
}
}
核心代码如上,就是不断的从请求队列中移出来一个请求,如果请求队列为空就会阻塞在这里(具体查看队列的take()方法)。接着就是对这个请求的一系列操作了。如果该请求已经取消了则直接finish掉,然后判断这个请求是否为空,如果为空则加入网络请求队列,如果不为空时,如果已经过期则也加入网络请求队列否则不需要加入网络请求队列,直接从缓存中获取数据。
4:networkDispatcher.start()方法的具体实现
request.addMarker(“network-queue-take”);
if(request.isCanceled()) {
request.finish(“network-discard-cancelled”);
} else {
this.addTrafficStatsTag(request);
NetworkResponse e = this.mNetwork.performRequest(request);
request.addMarker(“network-http-complete”);
if(e.notModified && request.hasHadResponseDelivered()) {
request.finish(“not-modified”);
} else {
Response response = request.parseNetworkResponse(e);
request.addMarker(“network-parse-complete”);
if(request.shouldCache() && response.cacheEntry != null) {
this.mCache.put(request.getCacheKey(), response.cacheEntry);
request.addMarker(“network-cache-written”);
}
request.markDelivered();
this.mDelivery.postResponse(request, response);
}
}
核心代码如上,首先看NetworkResponse e = this.mNetwork.performRequest(request)这句,而这里面的mNetwork是一个接口,它真正的实现是第一步初始化时传进去的BasicNetwork,在这个类中可以查看performRequest的具体实现。
HashMap e = new HashMap();
this.addCacheHeaders(e, request.getCacheEntry());
httpResponse = this.mHttpStack.performRequest(request, e);
StatusLine statusCode1 = httpResponse.getStatusLine();
int networkResponse1 = statusCode1.getStatusCode();
Map responseHeaders1 = convertHeaders(httpResponse.getAllHeaders());
if(networkResponse1 != 304) {
byte[] responseContents1;
if(httpResponse.getEntity() != null) {
responseContents1 = this.entityToBytes(httpResponse.getEntity());
} else {
responseContents1 = new byte[0];
}
long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
this.logSlowRequests(requestLifetime, request, responseContents1, statusCode1);
if(networkResponse1 >= 200 && networkResponse1 <= 299) {
return new NetworkResponse(networkResponse1, responseContents1, responseHeaders1, false);
}
throw new IOException();
}
return new NetworkResponse(304, request.getCacheEntry() == null?null:request.getCacheEntry().data, responseHeaders1, true);
这个方法的核心代码如上,找关键点。httpResponse = this.mHttpStack.performRequest(request, e);首先调用mHttpStack的performRequest方法来
解析网络请求,这个mHttpStack就是一开始初始化RequestQueue时创建的stack,其内部就是调用HttpURLConnection或者HttpClient来发送网络请求。之后就是经过一系列
的组装生成一个NetworkResponse返回。接下来要做关注的就是networkDispatcher.start()的两句代码,
Response response = request.parseNetworkResponse(e);和this.mDelivery.postResponse(request, response);
先看看Response response = request.parseNetworkResponse(e),parseNetworkResponse方法是我们自定义request时必须实现的方法,就是说不同request的解析有我们自定义的request中自己完成。因为不同种类的request的解析方式肯定是不同的。
再看看this.mDelivery.postResponse(request, response),这个mDelivery就是在RequestQueue的构造函数中传进来的
public RequestQueue(Cache cache, Network network, int threadPoolSize) {
this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper())));
}
即this.mDelivery.postResponse(request, response)调用的是ExecutorDelivery类的postResponse方法。通过ExecutorDelivery类的创建可知它是运行在主线程的。而ExecutorDelivery类的postResponse方法会启动一个线程,这个线程的run方法是
public void run() {
if(this.mRequest.isCanceled()) {
this.mRequest.finish(“canceled-at-delivery”);
} else {
if(this.mResponse.isSuccess()) {
this.mRequest.deliverResponse(this.mResponse.result);
} else {
this.mRequest.deliverError(this.mResponse.error);
}
if(this.mResponse.intermediate) {
this.mRequest.addMarker(“intermediate-response”);
} else {
this.mRequest.finish(“done”);
}
if(this.mRunnable != null) {
this.mRunnable.run();
}
}
}
可以看到当请求成功时会this.mRequest.deliverResponse(this.mResponse.result);而deliverResponse和parseNetworkResponse一样,也是我们自定义Request时自己实现的方法,这样在我们自己定义的Request的deliverResponse中就可以对我们发送的网络请求返回的结果做我们自己的处理了。
粗略解读,有误之处,还请指出