Volley是一款轻量级的网络访问框架,适合小批量的数据传输。Volley的使用通过newRequestQueue创建一个RequestQueue对象,并调用RequestQueue.add方法来提交任务。
![img_11b251e8875c97755b1dd039a3b743be.png](https://yqfile.alicdn.com/img_11b251e8875c97755b1dd039a3b743be.png)
newRequestQueue会根据系统版本号创建HttpStack(HttpUrlConnection或者HttpClient),这个是进行网络请求的API;最后调用了RequestQueue的start方法。
![img_69a3d5360f1401d2f42641a52cc6a85e.png](https://yqfile.alicdn.com/img_69a3d5360f1401d2f42641a52cc6a85e.png)
RequestQueue的构造函数会创建NetworkDispatcher数组,默认大小为4,也就是说可以Volley支持4个网络请求并发执行;Network用于网络请求操作;ExecutorDelivery用于将网络请求返回的数据同步发送个主线程。在构造完RequestQueue对象后,会调用start方法,实现如下:
![img_bfcbd3e8b8ba1c6e357ae6887df4d5ab.png](https://yqfile.alicdn.com/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](https://yqfile.alicdn.com/img_3f97cd18787c090ca2e8411e0f1944ba.png)
在创建完成StringRequest后,就可以通过RequestQueue.add方法将请求丢给Volley:
![img_557b76071dde00cfd3bfe4e54123ccd2.png](https://yqfile.alicdn.com/img_557b76071dde00cfd3bfe4e54123ccd2.png)
add方法首先判断Request是否是缓存请求,如果是就放入mCacheQueue中供CacheDispatcher调用,否则放入mNetworkQueue供NetworkDispatcher调用。
![img_5a8fbfda17939da6e5f56d60d263f64a.png](https://yqfile.alicdn.com/img_5a8fbfda17939da6e5f56d60d263f64a.png)
CacheDispatcher的实现如下:
![img_8233b7f2aab1a5d1117a1c7fd304f3ca.png](https://yqfile.alicdn.com/img_8233b7f2aab1a5d1117a1c7fd304f3ca.png)
![img_f75705b57ddde4b589d24698e9ed89d2.png](https://yqfile.alicdn.com/img_f75705b57ddde4b589d24698e9ed89d2.png)
![img_1f5d1f88910fdf6e0883552750a5dc5d.png](https://yqfile.alicdn.com/img_1f5d1f88910fdf6e0883552750a5dc5d.png)
首先会去本地缓存文件中查询该请求是否已经有获取到的结果,如果没有结果就说明获取缓存失败,将该请求加入mNetworkQueue中,由NetworkDispatcher调用。如果取到了缓存结果,就查看缓存是否已经过期,如果已经过期就将请求加入mNetworkQueue。如果缓存没有过期,就查看的新鲜度,看是否需要更新,如果不需要更新就直接将结果返回给调用端;需要更新的话就先将缓存结果交给调用方,同时将请求加入mNetworkQueue进行新鲜度验证。
![img_473d59760360f5b2562e0af9d4913d7d.png](https://yqfile.alicdn.com/img_473d59760360f5b2562e0af9d4913d7d.png)
在进行网络请求的时候,将Request加入到了NetworkDispatcher的队列中,并执行线程,调用方法如下:
![img_2a5874e7edd749b3be901043d1b62097.png](https://yqfile.alicdn.com/img_2a5874e7edd749b3be901043d1b62097.png)
![img_08403b7cc8dea0f58634fb0e5be5243a.png](https://yqfile.alicdn.com/img_08403b7cc8dea0f58634fb0e5be5243a.png)
mNetwork的实现是BasicNetwork,通过调用mNetwork.performRequest进行网络请求,然后根据需要将NetworkReponse进行缓存,最后将通过mDilivery将结果返回给调用方。mNetwork内部就是创建HttpUrlConnection,并完成请求。
![img_b7d242842c7255bb405a441e51a2df88.png](https://yqfile.alicdn.com/img_b7d242842c7255bb405a441e51a2df88.png)
BasicNetwork.performRequest将网络请求转给mBaseHttpStack,mBaseHttpStack的实现是HurlStack,HurlStack会进行网络数据的获取,BasicNetwork会对HurlStack的结果进行分析,并返回NetworkResponse。
![img_d55918a836aead434106f97e6e9aee91.png](https://yqfile.alicdn.com/img_d55918a836aead434106f97e6e9aee91.png)
可以看到,HurlStack.executeRequest通过获取HttpUrlConnection的InputStream来获取网络数据,将网络数据封装成HttpResponse。
NetworkDispatcher获取到NetworkResponse,,就通过mDilivery将网络数据回调给调用方,至此,整改网络请求结束。