Volley源码解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Volley是一款轻量级的网络访问框架,适合小批量的数据传输。Volley的使用通过newRequestQueue创建一个RequestQueue对象,并调用RequestQueue.add方法来提交任务。

Volley是一款轻量级的网络访问框架,适合小批量的数据传输。Volley的使用通过newRequestQueue创建一个RequestQueue对象,并调用RequestQueue.add方法来提交任务。

img_11b251e8875c97755b1dd039a3b743be.png
创建RequestQueue

newRequestQueue会根据系统版本号创建HttpStack(HttpUrlConnection或者HttpClient),这个是进行网络请求的API;最后调用了RequestQueue的start方法。

img_69a3d5360f1401d2f42641a52cc6a85e.png
启动RequestQueue

RequestQueue的构造函数会创建NetworkDispatcher数组,默认大小为4,也就是说可以Volley支持4个网络请求并发执行;Network用于网络请求操作;ExecutorDelivery用于将网络请求返回的数据同步发送个主线程。在构造完RequestQueue对象后,会调用start方法,实现如下:

img_bfcbd3e8b8ba1c6e357ae6887df4d5ab.png

start方法会初始化CacheDispatcher,CacheDispatcher是Thread的子类,然后运行CacheDispatcher线程,创建CacheDispatcher时会传一个mCacheQueue队列,这是一个PriorityBlockingQueue,用于保存缓存请求,CacheDispatcher的run方法会循环阻塞获取该队列里面的内容;除此之外还传递了mNetworkQueue队列,在获取缓存失败的时候,任务会再次放入mNetworkQueue中,交给NetworkDispatcher进行处理;之后会给mDispatcher数组中的每个NetworkDispatcher赋值,NetworkDispatcher也是Thread的子类,最后会起点每个NetworkDispatcher线程,创建的NetworkDispatcher的run方法会循环阻塞获取mNetworkQueue里面的网络请求。

在创建完RequestQueue请求队列后,下面就是建立请求,请求的方式包括StringRequest、JsonRequest、ImageRequest等,以StringRequest为例:

其中parserNetworkResponse是将网络请求返回的byte数据转化为String;deliverResponse是将String类型的返回值交给网络请求的发送方,这个发送方的回调在创建StringRequest的时候传进来。

img_3f97cd18787c090ca2e8411e0f1944ba.png
StringRequest

在创建完成StringRequest后,就可以通过RequestQueue.add方法将请求丢给Volley:

img_557b76071dde00cfd3bfe4e54123ccd2.png
RequestQueue.add

add方法首先判断Request是否是缓存请求,如果是就放入mCacheQueue中供CacheDispatcher调用,否则放入mNetworkQueue供NetworkDispatcher调用。

img_5a8fbfda17939da6e5f56d60d263f64a.png
请求流程

CacheDispatcher的实现如下:

img_8233b7f2aab1a5d1117a1c7fd304f3ca.png
img_f75705b57ddde4b589d24698e9ed89d2.png
img_1f5d1f88910fdf6e0883552750a5dc5d.png
CacheDispatcher.processRequest

首先会去本地缓存文件中查询该请求是否已经有获取到的结果,如果没有结果就说明获取缓存失败,将该请求加入mNetworkQueue中,由NetworkDispatcher调用。如果取到了缓存结果,就查看缓存是否已经过期,如果已经过期就将请求加入mNetworkQueue。如果缓存没有过期,就查看的新鲜度,看是否需要更新,如果不需要更新就直接将结果返回给调用端;需要更新的话就先将缓存结果交给调用方,同时将请求加入mNetworkQueue进行新鲜度验证。

img_473d59760360f5b2562e0af9d4913d7d.png
缓存请求流程

在进行网络请求的时候,将Request加入到了NetworkDispatcher的队列中,并执行线程,调用方法如下:

img_2a5874e7edd749b3be901043d1b62097.png
img_08403b7cc8dea0f58634fb0e5be5243a.png
NetworkDispatcher.processRequest

mNetwork的实现是BasicNetwork,通过调用mNetwork.performRequest进行网络请求,然后根据需要将NetworkReponse进行缓存,最后将通过mDilivery将结果返回给调用方。mNetwork内部就是创建HttpUrlConnection,并完成请求。

img_b7d242842c7255bb405a441e51a2df88.png
BasicNetwork.performRequest

BasicNetwork.performRequest将网络请求转给mBaseHttpStack,mBaseHttpStack的实现是HurlStack,HurlStack会进行网络数据的获取,BasicNetwork会对HurlStack的结果进行分析,并返回NetworkResponse。

img_d55918a836aead434106f97e6e9aee91.png
HurlStack.executeRequest

可以看到,HurlStack.executeRequest通过获取HttpUrlConnection的InputStream来获取网络数据,将网络数据封装成HttpResponse。

NetworkDispatcher获取到NetworkResponse,,就通过mDilivery将网络数据回调给调用方,至此,整改网络请求结束。

目录
相关文章
|
18天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
39 0
|
18天前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
29 0
|
18天前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
32 0
|
18天前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
44 0
|
16天前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
39 5
|
18天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
18天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
18天前
|
算法 Java 程序员
Map - TreeSet & TreeMap 源码解析
Map - TreeSet & TreeMap 源码解析
29 0
|
18天前
|
Java 容器
Collection-LinkedList源码解析
Collection-LinkedList源码解析
11 0
|
18天前
|
存储 Java 编译器
Collection-ArrayList源码解析
Collection-ArrayList源码解析
13 0

推荐镜像

更多