(点击上方公众号,可快速关注)
来源:刘望舒
链接:blog.csdn.net/itachi85/article/details/51104301
接上文
} catch (InterruptedException var4) {
if(this.mQuit) {
return;
}
}
}
}
}
}
}
static {
DEBUG = VolleyLog.DEBUG;
}
看到四个while循环有些晕吧,让我们挑重点的说,首先从缓存队列取出请求,判断是否请求是否被取消了,如果没有则判断该请求是否有缓存的响应,如果有并且没有过期则对缓存响应进行解析并回调给主线程。接下来看看网络调度线程。
4.NetworkDispatcher网络调度线程
NetworkDispatcher的run()方法:
public void run() {
Process.setThreadPriority(10);
while(true) {
long startTimeMs;
Request request;
while(true) {
startTimeMs = SystemClock.elapsedRealtime();
try {
//从队列中取出请求
request = (Request)this.mQueue.take();
break;
} catch (InterruptedException var6) {
if(this.mQuit) {
return;
}
}
}
try {
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 volleyError1 = request.parseNetworkResponse(e);
request.addMarker("network-parse-complete");
if(request.shouldCache() && volleyError1.cacheEntry != null) {
//将响应结果存入缓存
this.mCache.put(request.getCacheKey(), volleyError1.cacheEntry);
request.addMarker("network-cache-written");
}
request.markDelivered();
this.mDelivery.postResponse(request, volleyError1);
}
}
} catch (VolleyError var7) {
var7.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
this.parseAndDeliverNetworkError(request, var7);
} catch (Exception var8) {
VolleyLog.e(var8, "Unhandled exception %s", new Object[]{var8.toString()});
VolleyError volleyError = new VolleyError(var8);
volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
this.mDelivery.postError(request, volleyError);
}
}
}
网络调度线程也是从队列中取出请求并且判断是否被取消了,如果没取消就去请求网络得到响应并回调给主线程。请求网络时调用this.mNetwork.performRequest(request),这个mNetwork是一个接口,实现它的类是BasicNetwork,我们来看看BasicNetwork的performRequest()方法:
public NetworkResponse performRequest(Request?> request) throws VolleyError {
long requestStart = SystemClock.elapsedRealtime();
while(true) {
HttpResponse httpResponse = null;
Object responseContents = null;
Map responseHeaders = Collections.emptyMap();
try {
HashMap e = new HashMap();
this.addCacheHeaders(e, request.getCacheEntry());
httpResponse = this.mHttpStack.performRequest(request, e);
StatusLine statusCode1 = httpResponse.getStatusLine();
int networkResponse1 = statusCode1.getStatusCode();
responseHeaders = convertHeaders(httpResponse.getAllHeaders());
if(networkResponse1 == 304) {
Entry requestLifetime2 = request.getCacheEntry();
if(requestLifetime2 == null) {
return new NetworkResponse(304, (byte[])null, responseHeaders, true, SystemClock.elapsedRealtime() - requestStart);
}
requestLifetime2.responseHeaders.putAll(responseHeaders);
return new NetworkResponse(304, requestLifetime2.data, requestLifetime2.responseHeaders, true, SystemClock.elapsedRealtime() - requestStart);
}
...省略
从上面可以看到在12行调用的是HttpStack的performRequest()方法请求网络,接下来根据不同的响应状态码来返回不同的NetworkResponse。另外HttpStack也是一个接口,实现它的两个类我们在前面已经提到了就是HurlStack和HttpClientStack。让我们再回到NetworkDispatcher,请求网络后,会将响应结果存在缓存中,如果响应结果成功则调用this.mDelivery.postResponse(request, volleyError1)来回调给主线程。来看看Delivery的postResponse()方法:
public void postResponse(Request> request, Response> response, Runnable runnable) {
request.markDelivered();
request.addMarker("post-response");
this.mResponsePoster.execute(new ExecutorDelivery.ResponseDeliveryRunnable(request, response, runnable));
}
来看看ResponseDeliveryRunnable里面做了什么:
private class ResponseDeliveryRunnable implements Runnable {
private final Request mRequest;
private final Response mResponse;
private final Runnable mRunnable;
public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
this.mRequest = request;
this.mResponse = response;
this.mRunnable = runnable;
}
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();
}
}
}
}
第17行调用了this.mRequest.deliverResponse(this.mResponse.result),这个就是实现Request抽象类必须要实现的方法,我们来看看StringRequest的源码:
public class StringRequest extends Request {
private final Listener mListener;
public StringRequest(int method, String url, Listener listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
}
public StringRequest(String url, Listener listener, ErrorListener errorListener) {
this(0, url, listener, errorListener);
}
protected void deliverResponse(String response) {
this.mListener.onResponse(response);
}
...省略
}
在deliverResponse方法中调用了this.mListener.onResponse(response),最终将response回调给了Response.Listener的onResponse()方法。我们用StringRequest请求网络的写法是这样的:
RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest mStringRequest = new StringRequest(Request.Method.GET, "http://www.baidu.com",
new Response.Listener() {
@Override
public void onResponse(String response) {
Log.i("wangshu", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("wangshu", error.getMessage(), error);
}
});
//将请求添加在请求队列中
mQueue.add(mStringRequest);
看到第5行整个Volley的大致流程都通了吧,好了关于Volley的源码就讲到这里。
------------- 推荐 ------------
范品社推出的极客T恤,含程序员、电影、美剧和物理题材,面料舒适、100%纯棉,有黑、白、灰、藏青色,单件 ¥59.9、两件减¥12、四件减¥28、六件减¥42,详见网店商品页介绍。
(上面为部分 T 恤款式)
网店地址:https://fanpinshe.taobao.com
淘口令:复制以下红色内容,然后打开手淘即可购买
范品社,使用¥极客T恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)