[关闭]
@946898963 2018-05-18T03:27:14.000000Z 字数 3795 阅读 933

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

Android控件跟框架 Android源码分析


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

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

  1. public interface ResponseDelivery {
  2. public void postResponse(Request<?> request, Response<?> response);
  3. public void postResponse(Request<?> request, Response<?> response, Runnable runnable);
  4. public void postError(Request<?> request, VolleyError error);
  5. }

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

  1. public class ExecutorDelivery implements ResponseDelivery {
  2. private final Executor mResponsePoster;
  3. public ExecutorDelivery(final Handler handler) {
  4. mResponsePoster = new Executor() {
  5. @Override
  6. public void execute(Runnable command) {
  7. handler.post(command);
  8. }
  9. };
  10. }
  11. public ExecutorDelivery(Executor executor) {
  12. mResponsePoster = executor;
  13. }
  14. @Override
  15. public void postResponse(Request<?> request, Response<?> response) {
  16. postResponse(request, response, null);
  17. }
  18. @Override
  19. public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
  20. request.markDelivered();
  21. request.addMarker("post-response");
  22. mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
  23. }
  24. @Override
  25. public void postError(Request<?> request, VolleyError error) {
  26. request.addMarker("post-error");
  27. Response<?> response = Response.error(error);
  28. mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
  29. }
  30. @SuppressWarnings("rawtypes")
  31. private class ResponseDeliveryRunnable implements Runnable {
  32. private final Request mRequest;
  33. private final Response mResponse;
  34. private final Runnable mRunnable;
  35. public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
  36. mRequest = request;
  37. mResponse = response;
  38. mRunnable = runnable;
  39. }
  40. @SuppressWarnings("unchecked")
  41. @Override
  42. public void run() {
  43. if (mRequest.isCanceled()) {
  44. mRequest.finish("canceled-at-delivery");
  45. return;
  46. }
  47. if (mResponse.isSuccess()) {
  48. mRequest.deliverResponse(mResponse.result);
  49. } else {
  50. mRequest.deliverError(mResponse.error);
  51. }
  52. if (mResponse.intermediate) {
  53. mRequest.addMarker("intermediate-response");
  54. } else {
  55. mRequest.finish("done");
  56. }
  57. if (mRunnable != null) {
  58. mRunnable.run();
  59. }
  60. }
  61. }
  62. }

构造方法:

  1. private final Executor mResponsePoster;
  2. public ExecutorDelivery(final Handler handler) {
  3. //传入的Handler与主线程绑定了,所以分发的消息最终是运行在主线程中的
  4. mResponsePoster = new Executor() {
  5. @Override
  6. public void execute(Runnable command) {
  7. handler.post(command);
  8. }
  9. };
  10. }
  11. public ExecutorDelivery(Executor executor) {
  12. mResponsePoster = executor;
  13. }

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

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

  1. //RequestQueue的构造方法中创建了ExecutorDelivery
  2. 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. public void run() {
  2. // 如果请求被中断,那么就不需要发送响应了
  3. if (mRequest.isCanceled()) {
  4. mRequest.finish("canceled-at-delivery");
  5. return;
  6. }
  7. // 如果服务器响应成功,中途没有错误的发生
  8. if (mResponse.isSuccess()) {
  9. // 将服务器返回的结果发送给客户端
  10. mRequest.deliverResponse(mResponse.result);
  11. } else {
  12. // 把错误发送给客户端
  13. mRequest.deliverError(mResponse.error);
  14. }
  15. // 中间响应
  16. if (mResponse.intermediate) {
  17. mRequest.addMarker("intermediate-response");
  18. } else {
  19. //请求结束
  20. mRequest.finish("done");
  21. }
  22. // 启动附加线程
  23. if (mRunnable != null) {
  24. mRunnable.run();
  25. }
  26. }

而run方法中是通过

  1. mRequest.deliverResponse(mResponse.result);

对结果进行分发的。

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

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

调用回调方法。

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

参考链接:

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

Volley源码解析<七> ResponseDelivery和ExecutorDelivery

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注