Volley完全解析——使用、源码
Feathers's Volley and Demo:https://github.com/xf616510229/VolleyDemo.git
Volley简介
2013年Google I/O大会上推出了一个新的网络通信框架——Volley,它简单易用,适合通信频繁的操作,不适合大数据量的操作 volley本来的意思就是集中射击、集鸣:

下载Volley
Git:git clone https://android.googlesource.com/platform/frameworks/volley ,然后让项目依赖此文件 Gradle: compile 'com.android.volley:volley:1.0.0' 或是在dependencies中搜索并依赖,一般第一个就是
注意:Module app 中使用的是:compile 'eu.the4thfloor.volley:com.android.volley:2015.05.28' 该compile多了一些功能,比如
ImageRequest.Transformation
官方文档:https://developer.android.com/training/volley/index.html doc:http://afzaln.com/volley/
Volley的使用
StringRequest
设置请求方法
子类JsonRequest/JsonArrayRequest
ImageRequest
ImageLoader
NetworkImageView
自定义GsonRequest
请看类GsonRequest
自定义XMLRequest
请看类XMLRequest
Demo效果: 
Volley源码解析

Request added to queue in priority order
Request dequeued by CacheDispatcher
cache hit: request read from cache and parsed
cache miss:cache dequeued by NetworkDispatcher(round-robin)
HTTP、HTTP transaction,response parse,cache write(if applicable)、HTTP
Parsed response delivered on main thread.
源码解析
解析源码,首先要从他的方法上着手
创建一个RequestQueue
我们从源码上可以看到,newRequestQueue最终都是调用三个参数的构造方法完成的,七种的三个参数分别为:
context
HttpStack
maxDiskCacheBytes 磁盘缓存最大值,默认是-1,如果小于0,代表没有缓存最大限制
相信你们看完之后最疑惑的地方就是在于HttpStack了,让我们看一下HttpStack:
HttpStack
HttpStack是一个接口,只有一个抽象方法:performRequest,需要三个参数
request
additionalHeaders,附加的请求头,请求头信息大都是键值对,所以此处使用Map集合
根据方法的名字,以及返回值Response,可以初步判断,该类是用于执行请求的,为了证实猜想,我们看看他的两个子类: HurlStack HttpClientStack
HttpClientStack就相对简单了,对请求作出了一些相应的处理,然后执行获取了response对象
HttpStack就是这样,它的功能主要还是让执行request,获取response
然后,第四步骤中,又使用这个stack对象生成了一个Network实例,让我们看一下Network
Network
又是一个接口,我们看到,Network中也只有一个方法,也叫performRequest,执行请求, 返回的同样也是response对象,但是是NetworkResponse对象,其中包含了相应码,响应头,响应体等信息
BasicNetwork:
Network的performRequest就是调用HttpStack的performRequest方法,根据不同的情况进行不同方式的网络请求,获取response
然后,对queue进行初始化,此时才真正初始化queue
可以看到,RequestQueue共有三个构造器,最终都指向四个参数的构造器 四个参数分别为
Cache缓存类
Network类
threadPoolSize,线程池线程数量
ResponseDelivery ?
先看Cache接口:
Cache接口中提供了存取缓存的方法,和一个保存缓存信息的内部类Entry Network提供了执行request的方法 默认的网络线程池的大小为4:
构造器拿着这个大小,创建了一个NetworkDispatcher数组,这个类我们等用到时去看。
至此,requestQueue已经初始化完成,接着就调用了start()方法
我们看到注释是start the dispatchers in the queue,下文中又启动了CacheDispatchers与NetworkDispatcher
我们先看一看创建CacheDispatcher传入的参数的初始化:
所谓的cacheQueue,就是一个泛型为Request的队列,networkQueue也是,自行配图观看~
注:PriorityBlockingQueue 是Java7推出的含有优先级的队列集合
CacheQueue继承Thread类, 让我们看看CacheDispatcher的构造器:
我们从构造器的注释上看得很清楚,这个类会创建一个新的用于对request缓存队列进行缓存处理的线程,调用start()方法启动线程。 让我们看看run(),他究竟做了些什么:
我们紧接着看一看NetworkDispatcher:
我们看到: NetworkResponse networkResponse = mNetwork.performRequest(request); 在执行run()时,调用了performRequest(request)获取了response,前面说过,这个方法就是进行网络请求的真正的方法
无论是CacheDispatcher 还是 NetworkDispatcher 最后都执行了mDelivery.postResponse()方法,这个方法用来解析来自缓存或者网络响应,而且是抛给主线程处理: 我们看看这个方法:
我们看到这个方法调用了mResponsePoster.execute(),mResponsePoster是一个Runnable 他是ExecutorDelivery的内部类,调用execute(),回去执行run() 如下:
我们看到请求成功的时候,将response.result交给了Request: Request有如下几个实现类: StringRequest ClearCacheRequest ImageRequest 以StringRequest为例:
deliverResponse将response交给listener处理,而这个listener就是我们进行回调处理response的Listener
至此整个流程也就结束。
总结
Volley的大体流程:
将请求添加到缓存队列
在缓存线程中处理缓存队列中的请求
如果缓存存在,抛给主线程,进行对response处理
如果缓存不存在,将request抛给网络请求队列,在网络线程中遍历处理request
然后进行写缓存,仍在网络线程中。
最好抛给主线程,对response处理
最后更新于
这有帮助吗?