Volley 是 Google 在2013年 Google I/O 大会上推出的一款 Android 异步网络请求框架。名字的由来:
|
|
它的特点:适合 数据量小、通信频繁 的网络操作。我们可以从 github 上下载它的源码,地址:https://github.com/google/volley
Volley 整体设计
新建一个 Request 请求,将其添加到 RequestQueue 中,这里有一个判断,首先新建一个 CacheDispatcher(继承自 Thread) 判断内存中是否存在,如果存在就从内存中去;否则新建 NetworkDispatcher 去执行网络请求。最后通过 ResponseDelivery 处理反馈回来的数据。
Volley 中相关概念
Volley
一个工具类,它里面只有简单的几行代码,通过 newRequestQueue(…) 函数新建并启动一个请求队列 RequestQueue。
|
|
上述代码中,进行了系统版本的判断,如果版本号大于9,就选择 HurlStack,否则就 HttpClientStack,HurlStack 是基于 HttpUrlConnection 的,HttpClientStack 是基于 Apache HttpClient 的;最主要的两句代码:
|
|
在 RequestQueue 中需要传入两个参数,第一个参数是缓存路径,第二个参数是 Network。通过 start() 方法来完成队列的创建和启动。
Request
它是一个抽象类,如果要实现请求,必须继承于它,StringRequest、JsonRequest、ImageRequest 都是它的子类。
|
|
子类必须重写它的两个方法:
|
|
Request 代码如下:
|
|
Request 实现了 Comparable 接口,说明 Request 是可以互相比较的,比较的内容就是两个 Request 的 priority。
RequestQueue
Volley 框架的核心类,将请求 Request 加入到 RequestQueue 中,来完成请求操作。代码如下:
|
|
- 1.主要成员变量
在 RequestQueue 中,维护了两个基于优先级的 Request 队列:缓存请求队列和网络请求队列。
|
|
维护了一个正在进行中,尚未完成的请求集合:
|
|
维护了一个等待请求的集合,如果一个请求正在被处理并且可以被缓存,后续的相同的 url 的请求,将进入到此等待队列中。
|
|
RequestQueue 的初始化,如下:
|
|
- 2.启动队列
调用 start() 方法,启动队列。
|
|
在上述代码中,首先调用 stop() 结束所有的缓存请求和网络请求。之后开启一个 缓存调度线程 CacheDispatcher 和默认是4个的网络调度线程 NetworkDispatcher,缓存调度线程不断的从缓存请求队列中取出 Request 去处理,网络调度线程不断地从网络请求队列中取出 Request 去处理。stop() 代码如下:
|
|
- 3.加入请求
调用 add() 方法完成 Request 添加到 RequestQueue 的过程。代码如下:
|
|
上述代码的流程图如下:
- 4.请求完成
调用 finish()方法结束 Request 请求,代码如下:
|
|
在上述代码中,首先从正在进行中请求集合 mCurrentRequests 中移除该请求,然后查找请求等待集合 mWaitingRequests 中是否存在等待请求,如果存在,则将其在等待队列移除,并将等待队列所有的请求添加到缓存请求队列中,让缓存请求处理线程 CacheDispatcher 去处理。
- 5.请求取消
取消当前请求集合中所有符合条件的请求。
|
|
filter 参数表示按照自定义的过滤器需要取消请求。
|
|
tag 表示按照 Request.setTag() 设置好的 tag 取消请求。
CacheDispatcher
继承自Thread,用于处理缓存的请求,不断从缓存队列中取出请求,队列为空则等待,请求处理结束则将结果传递给 ReponseDelivery 去执行后续处理;当结果未缓存过、缓存失效或者缓存需要刷新的情况下,该请求将会交给 NetworkDispatcher 去处理。代码如下:
|
|
从上述代码中,我们可以知道在 run() 方法中的处理流程如下:
NetworkDispatcher
继承 Thread,用于处理网络请求。启动之后不断的从网络请求队列中取出请求,队列为空则等待,请求处理结束则将结果传递给 ResponseDelivery 去执行后续处理,并判断结果是否需要进行缓存。代码如下:
|
|
上述代码中,处理逻辑如下:
Cache
它是一个接口,用于将请求结果进行缓存。里面主要有 put/get/remove/clear() 方法,还有一个实体类 Entry 用于存储该类的成员变量和方法。代码如下:
|
|
其中,
- tag — Http 响应首部中用于缓存新鲜度验证的 ETag
- serverDate — Http 响应首部中的响应产生时间
- ttl — 缓存的过期时间
- softTtl — 缓存的新鲜时间
- isExpired — 判断缓存是否过期,过期缓存将不再使用
- refreshNeeded() — 判断缓存是否新鲜,不新鲜的缓存需要发到服务端坐新鲜度的检测。
Network
表示网络请求的接口,处理网络请求,里面只有唯一的方法:
|
|
NetworkResponse
它是网络请求和缓存请求回来的额结果,是 Request 的 parseNetworkResponse(…) 的参数,它里面封装了网络请求响应的 StatusCode、Headers和 Body 等。如下:
|
|
NetworkResponse 的流程图如下:
Response
封装了经过解析之后的数据,用于传输。在内部有两个接口 Listener 和 ErrorListener 分别表示请求成功和失败的回调。 Response 的构造函数被私有化,而通过两个静态方法 success() 和 error() 来创建对象。代码如下:
|
|
ResponseDelivery
请求结果的传输接口,用于传递请求结果或者请求错误。如下:
|
|
ExecutorDelivery
请求结果传输接口具体实现类,在 handler 对应线程中传输缓存调度线程或者网络调度线程中产生的请求结果或者请求错误,请求成功时调用 Request.deliverResponse() 方法,失败时调用 Request.deliverError() 方法。代码如下:
|
|
RetryPolicy
重试策略接口,里面有三个方法,但只有 retry() 方法是有用的。如下:
|
|
retry() 方法,表示是否重试。在请求异常时此接口会被调用,可在此函数实现中抛出错误的异常表示停止重试。
DefaultRetryPolicy
RetryPolicy 的实现类,Volley 默认的重试策略主要是通过在 retry() 函数中红判断重试次数是否达到上限确定是否需要重试。代码如下:
|
|
到此为止,Volley 的主要类的源码就分析完啦,它里面还有很多工具类,很值得深入了解,下次继续努力。
参考文章: