Volley源码解析

使用Volley整体流程:

 

总体设计图

这里写图片描述

 

 

1.  Request类型及类图

 

 

 

2. RequestQueue

/frameworks/volley/src/com/android/volley/RequestQueue.java

  PriorityBlockingQueue<Request<?>> mCacheQueue

  PriorityBlockingQueue<Request<?>> mNetworkQueue

  mCacheQueue 和 mNetworkQueue 都是用来存放Request的

  当RequestQueue中add一个Request后,如果该请求不加入Cache则直接加入mNetworkQueue,等待Network处理该请求;或者先放入mCacheQueue等待CacheDispatcher的处理;

   RequestQueue的start() 方法

 

RequestQueue的 add 方法 

对于新add的request, 设置归属队列,放入mCurrentRequest 表示正在处理,并设置一下加入队列的顺序,

需要需要对该request进行Cache, 

    不需要Cache则直接放入networkQueue等待网络访问

    需要放入cache,则要先查询是否已经有相同的请求在等待

          如果没有,则直接放入CacheQueue等待调度,

          如果有等待, 则也要加入mWritingRequests,排队等候

RequestQueue的 finish 方法 

这个方法在Request#finish(String)中被调用, 用来表示Request已经完成,将在mCurrentRequests中移除;

如果要放入Cache, 则要在mWaitingRequests中相同的正在等待的请求移除, 然后将请求放到mCacheQueue中

 

RequestQueue的 cancelAll 方法 

public void cancelAll(RequestFilter filter) —— 自己定义一个RequestFilter, 所有符合这个fiflter的都将被标志为 mCanceled = true;

public void cancelAll(final Object tag) —— 所有request.getTag() == tag 的 Request 都会被标志为 mCanceled = true;

 

 

/frameworks/volley/src/com/android/volley/toolbox/RequestFuture.java

 

 

3. Dispatch Thread

/frameworks/volley/src/com/android/volley/CacheDispatcher.java

public class CacheDispatcher extends Thread

Provides a thread for performing cache triage on a queue of requests.

Requests added to the specified cache queue are resolved from cache.
Any deliverable response is posted back to the caller via a {@link ResponseDelivery}.  
Cache misses and responses that require refresh are enqueued on the specified network queue for processing by a {@link NetworkDispatcher}.
  •   它是一个Thread, 作用是 对 RequestQueue执行缓存调度;
  •   从Cache中解析出来的Request 被添加到指定的CacheQueue. 
  •   任何可交付的response都被ResponseDelivery传回给调用者.
  •   未命中的Cache & 需要刷新的reponse 都要被 NetworkDispatcher 添加到指定的 NetworkQueue

run函数流程图

 

 

 

/frameworks/volley/src/com/android/volley/NetworkDispatcher.java

public class NetworkDispatcher extends Thread

特殊点: TrafficStats.setThreadStatsTag(request.getTrafficStatsTag()); 流量统计API, 用来标记线程内部发生的数据传输情况

 

线程run()方法流程图

 

4. Get Data Interface部分

4.1 Cache 类型

/frameworks/volley/src/com/android/volley/Cache.java
/frameworks/volley/src/com/android/volley/toolbox/DiskBasedCache.java
/frameworks/volley/src/com/android/volley/toolbox/NoCache.java

4.2 网络访问组件: 

/frameworks/volley/src/com/android/volley/toolbox/HttpStack.java
/frameworks/volley/src/com/android/volley/toolbox/HttpClientStack.java
/frameworks/volley/src/com/android/volley/toolbox/HurlStack.java

 

/frameworks/volley/src/com/android/volley/Network.java
/frameworks/volley/src/com/android/volley/toolbox/BasicNetwork.java

实现超类Network的performRequest方法

BasicNetwork.performRequest方法

    将参数request提取关键数据,调用 mHttpStack.performRequest(request, headers) 发起网络访问, 分解反馈httpResponse的 statusCode 封装不同的 NetworkResponse;

    如果中间发生了异常 例如 SocketTimeoutException, ConnectTimeoutException, 或者statusCode == HttpStatus.SC_UNAUTHORIZED || statusCode == HttpStatus.SC_FORBIDDEN, 那么根据 重试策略进行 重新访问

 

Delivery相关

/frameworks/volley/src/com/android/volley/ResponseDelivery.java
/frameworks/volley/src/com/android/volley/ExecutorDelivery.java

ExecutorDelivery的postResponse方法执行一个ResponseDeliveryRunnable线程,将response传给用户。

ResponseDeliveryRunnable线程run()函数流程如下:

 

 

Retry重试策略

/frameworks/volley/src/com/android/volley/RetryPolicy.java
/frameworks/volley/src/com/android/volley/DefaultRetryPolicy.java

 

Response类型

/frameworks/volley/src/com/android/volley/Response.java

/frameworks/volley/src/com/android/volley/NetworkResponse.java

 

几种错误处理

/frameworks/volley/src/com/android/volley/VolleyError.java
/frameworks/volley/src/com/android/volley/TimeoutError.java
/frameworks/volley/src/com/android/volley/NetworkError.java
/frameworks/volley/src/com/android/volley/NoConnectionError.java
/frameworks/volley/src/com/android/volley/ServerError.java
/frameworks/volley/src/com/android/volley/AuthFailureError.java
/frameworks/volley/src/com/android/volley/ParseError.java

 

 登录相关

/frameworks/volley/src/com/android/volley/toolbox/Authenticator.java
/frameworks/volley/src/com/android/volley/toolbox/AndroidAuthenticator.java

  

2.2. Volley 中的概念

简单介绍一些概念,在详细设计中会仔细介绍。 
Volley 的调用比较简单,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue后,只需要往这个RequestQueue不断 add Request 即可。

Volley:Volley 对外暴露的 API,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue。

Request:表示一个请求的抽象类。StringRequest、JsonRequest、ImageRequest 都是它的子类,表示某种类型的请求。

RequestQueue:表示请求队列,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。

CacheDispatcher:一个线程,用于调度处理走缓存的请求。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进入NetworkDispatcher去调度处理。

NetworkDispatcher:一个线程,用于调度处理走网络的请求。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理,并判断结果是否要进行缓存。

ResponseDelivery:返回结果分发接口,目前只有基于ExecutorDelivery的在入参 handler 对应线程内进行分发。

HttpStack:处理 Http 请求,返回请求结果。目前 Volley 中有基于 HttpURLConnection 的HurlStack和 基于 Apache HttpClient 的HttpClientStack。

Network:调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。

Cache:缓存请求结果,Volley 默认使用的是基于 sdcard 的DiskBasedCache。NetworkDispatcher得到请求结果后判断是否需要存储在 Cache,CacheDispatcher会从 Cache 中取缓存结果。

  1. 流程图 
    Volley 请求流程图 
    这里写图片描述
    上图是 Volley 请求时的流程图,在 Volley 的发布演讲中给出,我在这里将其用中文重新画出。
  2. 详细设计 
    4.1 类关系图 
    这里写图片描述
    这是 Volley 框架的主要类关系图

图中红色圈内的部分,组成了 Volley 框架的核心,围绕 RequestQueue 类,将各个功能点以组合的方式结合在了一起。各个功能点也都是以接口或者抽象类的形式提供。 
红色圈外面的部分,在 Volley 源码中放在了toolbox包中,作为 Volley 为各个功能点提供的默认的具体实现。 
通过类图我们看出, Volley 有着非常好的拓展性。通过各个功能点的接口,我们可以给出自定义的,更符合我们需求的具体实现。

多用组合,少用继承;针对接口编程,不针对具体实现编程。

 

 

 

 

 

 

 

 

 

 

posted @ 2015-11-17 20:47  carlo-z  阅读(1614)  评论(0编辑  收藏  举报