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源码解析

这里写图片描述
  1. Request added to queue in priority order

  2. Request dequeued by CacheDispatcher

  3. cache hit: request read from cache and parsed

  4. cache miss:cache dequeued by NetworkDispatcher(round-robin)

  5. HTTP、HTTP transaction,response parse,cache write(if applicable)、HTTP

  6. Parsed response delivered on main thread.

源码解析

解析源码,首先要从他的方法上着手

  1. 创建一个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的大体流程:

  1. 将请求添加到缓存队列

  2. 在缓存线程中处理缓存队列中的请求

  3. 如果缓存存在,抛给主线程,进行对response处理

  4. 如果缓存不存在,将request抛给网络请求队列,在网络线程中遍历处理request

  5. 然后进行写缓存,仍在网络线程中。

  6. 最好抛给主线程,对response处理

最后更新于

这有帮助吗?