Volley-ResponseDelivery及其实现类的源码解析

这部分主要介绍对响应结果进行分发的ResponseDelivery及其实现类ExecutorDelivery。

ResponseDelivery是一个接口,其定义了3个方法,2个传递response的重载方法与一个传递error的方法。

1
2
3
4
5
6
7
8
public interface ResponseDelivery {

public void postResponse(Request<?> request, Response<?> response);

public void postResponse(Request<?> request, Response<?> response, Runnable runnable);

public void postError(Request<?> request, VolleyError error);
}

其实现类ExecutorDelivery是真正执行的功能类。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class ExecutorDelivery implements ResponseDelivery {

private final Executor mResponsePoster;

public ExecutorDelivery(final Handler handler) {
mResponsePoster = new Executor() {
@Override
public void execute(Runnable command) {
handler.post(command);
}
};
}

public ExecutorDelivery(Executor executor) {
mResponsePoster = executor;
}

@Override
public void postResponse(Request<?> request, Response<?> response) {
postResponse(request, response, null);
}

@Override
public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
request.markDelivered();
request.addMarker("post-response");
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
}

@Override
public void postError(Request<?> request, VolleyError error) {
request.addMarker("post-error");
Response<?> response = Response.error(error);
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
}

@SuppressWarnings("rawtypes")
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) {
mRequest = request;
mResponse = response;
mRunnable = runnable;
}

@SuppressWarnings("unchecked")
@Override
public void run() {

if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}

if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}

if (mResponse.intermediate) {
mRequest.addMarker("intermediate-response");
} else {
mRequest.finish("done");
}

if (mRunnable != null) {
mRunnable.run();
}
}
}
}

构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private final Executor mResponsePoster;

public ExecutorDelivery(final Handler handler) {
//传入的Handler与主线程绑定了,所以分发的消息最终是运行在主线程中的
mResponsePoster = new Executor() {
@Override
public void execute(Runnable command) {
handler.post(command);
}
};
}

public ExecutorDelivery(Executor executor) {
mResponsePoster = executor;
}

其构造方法唯一目的就是实例化了Excutor类型的mResponsePoster。

Volley默认调用的是第一个构造方法,也就是包装了一个Handler。Volley在创建ExecutorDelivery的时候传入了一个与主线程的Looper关联的Handler,这样最终分发的消息就是在主线程中运行的,这样就可以在回调中操作UI了。

1
2
//RequestQueue的构造方法中创建了ExecutorDelivery
this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper()))

mResponsePoster使用线程池来管理线程,可以重复利用已经创建出来的线程而不是每次都必须新创建线程,节省了一部分的开销(有疑问)。也可以自定义线程池通过public ExecutorDelivery(Executor executor)构造函数传递过来。

该类最主要的方法是postResponse,其核心的实现

1
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));

执行的是ResponseDeliveryRunnable的run方法,run方法的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void run() {

// 如果请求被中断,那么就不需要发送响应了
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}

// 如果服务器响应成功,中途没有错误的发生
if (mResponse.isSuccess()) {
// 将服务器返回的结果发送给客户端
mRequest.deliverResponse(mResponse.result);
} else {
// 把错误发送给客户端
mRequest.deliverError(mResponse.error);
}

// 中间响应
if (mResponse.intermediate) {
mRequest.addMarker("intermediate-response");
} else {
//请求结束
mRequest.finish("done");
}

// 启动附加线程
if (mRunnable != null) {
mRunnable.run();
}
}

而run方法中是通过

1
mRequest.deliverResponse(mResponse.result);

对结果进行分发的。

而Request的该方法则是由有其具体的实现类StringRequest,JsonRequest,ImageRequest实现,其实现都一致,则是:

1
2
3
4
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}

调用回调方法。

至此,总结下整个分发流程,通过Dispatcher处理每个Request,对request处理完后,通过ResponseDelivery进行交付,其交付通过一个与UI线程绑定的handler来进行,通过该Handler的post将Response传递到主线中处理,最终会调用Request类的delivery方法,而在该方法中,又会调用我们构造request时,传入的回调方法。

参考链接:

Volley源码分析(四)NetWork与ResponseDelivery工作原理

Volley源码解析<七> ResponseDelivery和ExecutorDelivery

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器