简 介

1 Volley是在2013年谷歌发布的一款快捷高效、轻量级的网络通信框架,里面封装了HttpURLConnection和HttpClient的通信细节。

2 优点:
自动调度网络请求;
非常适合去进行数据量不大,但通信频繁的网络操作;
扩展性强。

3 缺点:
不适合大数据量的网络操作,比如文件的下载。

4 Volley的中文翻译为“齐射”,下图是其在发布演讲上的配图,可以看到很多弓箭在发射,每一个弓箭代表一个网络请求,喻指Volley框架是非常适合数据量不大但频繁的网络通信。所以在Volley源码的注释上,可以看到很多hit(击中)、in flight(飞行)等字样,结合其背景,就很好理解了。

HTTP通信

1 方式
Android系统中主要提供两种方式来进行HTTP通信,HttpURLConnection和HttpClient。

2 HttpURLConnection
优点:轻量极、API比较简单、易使用、可扩展 。。。
缺点:在Android 2.2版本之前,HttpURLConnection一直存在着一些bug,不太稳定。
简单使用:

3 HttpClient
优点:API多、比较稳定、bug数量也很少。
缺点:API数量过多,导致难在不破坏兼容性的情况下对它进行升级和扩展。
简单使用:

4 推荐
在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。
在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。

Volley对HTTP的封装

上面对HttpURLConnection和HttpClient只是简单的使用,在实际项目中,因为要考虑的场景很多,会有不同的请求参数,不同的请求方式,不同的响应结果等等,所以用起来还是稍微有点复杂,如果不进行适当封装的话,很容易就会写出不少重复代码。 但是,要做到性能、内存、结构、代码都很好的封装,很难,所以在项目中,如果涉及到网络请求,我们一般不会自己去写网络通信代码,而是直接使用一些开源的网络框架。

Volley中和网络通信相关的类图如下:

在Volley框架中:
如果Android SDK版本大于等于9,使用HurlStack这种网络请求方式,实际上HurlStack里面封装的就是HttpURLConnection方式。
如果Android SDK版本小于9,使用HttpClientStack这种网络请求方式,实际上HttpClientStack里面封装的就是HttpClient方式。

最后将网络请求方式注入到BasicNetwork类中, BasicNetwork属于Volley框架进行网络通信的接口类,这里使用了装饰者的设计模式。

自动调度请求

自动调度请求,是Volley框架的一个核心。
说起来很简单,类似 消息循环处理机制 。在Volley框架中,有1个网络请求队列(mNetworkQueue)和4个网络请求调度线程(NetworkDispatcher),这4个线程不断的从队列中获取请求,交由网络通信接口类(BasicNetwork)处理,并返回响应结果。

缓存机制

缓存机制,是Volley框架的另一个核心。
前面说过,Volley框架的优点是非常适合数据量不大,但通信频繁的网络操作,缺点在不适合大数据量的网络操作,原因就在这。

在Volley框架中,除了有1个网络请求队列(mNetworkQueue)和4个网络请求调度线程(NetworkDispatcher),还有1个缓存请求队列(mCacheQueue)和1个缓存请求调度线程(CacheDispatcher)。缓存调度线程不断的从缓存队列中取出请求处理。

和缓存相关的类图如下:

Entry是接口Cache的内部类,和请求响应结果相关的数据都缓存在这个数据结构里,并且记录在文件里。
缓存文件的路径是在/data/data/下,默认最大的缓存大小为5M。

处理请求流程

下面看下添加一个请求的处理流程(RequestQueue.add):

缓存线程的处理流程(CacheDispatcher):

网络线程的处理流程(NetworkDispatcher):

从上面的流程可以看出,封装网络通信的难点在于怎样用严密的逻辑去管理所有的请求。

使 用

第一步:创建一个RequestQueue对象。

RequestQueue mQueue = Volley.newRequestQueue(context);

在这里面创建并启动了上述的5个线程,Volley框架已经跑起来了。

注意RequestQueue的设计是高并发的,里面可以缓存所有的HTTP请求,然后按照一定的算法并发地发送出去,因此我们没有必要为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,基本上在一个应用上创建一个就可以了。

第二步:构建一个请求

Volley自带的请求类图如下:

1 以StringRequest为例:

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener); 

第一个参数为请求方式,get /post/put/delete…..
第二个参数就是目标服务器的URL地址;
第三个参数是服务器响应成功的回调;
第四个参数是服务器响应失败的回调。
比如请求百度的网址:

2 在Volley框架中还有一个RequestFuture,

public class RequestFuture<T> implements Future<T>, Response.Listener<T>,Response.ErrorListener {}

它可以阻塞等待响应结果,在项目中一般用这个作为请求的回调器。

3 所有的请求类都需要实现父类Request类中的两个抽象方法:

abstract protected Response<T> parseNetworkResponse(NetworkResponse response);//解析服务器返回的响应数据
abstract protected void deliverResponse(T response); //传送结果

我们看下在StringRequest中是怎么实现的?

这两个方法是怎么被框架调用的?

首先看下parseNetworkResponse方法的调用:

不管是从缓存线程中得到缓存的响应结果还是从网络线程中得到服务器响应结果,我们都是得到了NetworkResponse对象,然后就调用了request.parseNetworkRespons()将NetworkResponse对象传到各自请求,各自处理,再返回Response结果。

再看deliverResponse(T response)方法的调用:

上面我们得到了Response结果,是直接将这个结果传给deliverResponse吗?
不是,这里介绍volley框架里的另一个对象:ResponseDelivery(响应传送器)
在构建RequestQueue对象时,框架为我们new了这样一个对象mDelivery
(ExecutorDelivery extends ResponseDelivery),并且传入了主线程的Handler。

所以在上面得到了Response结果后,我们通过响应传送器将结果传出去了,

mDelivery.postResponse(request, response);

在响应传送器中将response构造成Runnable,交由主线程的Handler处理。在Runnable里,调用了request.deliverResponse(response),将response对象传到各自请求,各自处理。

所以,parseNetworkResponse方法是在子线程中执行的,而deliverResponse是在主线程中执行的。

4 对于图片请求,除了ImageRequest外,Volley还提供另一种方式:ImageLoader。

ImageLoader也可以用于加载网络上的图片,并且它的内部也是使用ImageRequest来实现的,不过ImageLoader明显要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。

这里不细讲这个,有兴趣的同学可以查阅相关资料或源码去了解。

第三步:添加一个请求

mQueue.add(stringRequest); 

通过这三步,一个最基本的HTTP发送与响应的功能就完成了。

扩 展

定制自己的请求,继承Request< T >

定制请求对象比较常用的几个方面:
第一,泛型参数T,即我们希望请求返回的数据类型;
第二,提交的请求参数,通过复写父类Request中的getParams()方法,提供请求的表单参数。

protected Map<String, String> getParams() throws AuthFailureError {return null;
}

第三,设置重试策略(请求失败,自动再次发起请求),一般在请求的构造器中设置,通过调用父类Request中的setRetryPolicy()方法。

public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {mRetryPolicy = retryPolicy;return this;
}

一般用框架提供的默认策略,可以设置连接超时时间,重试次数。

public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {}

简单的文件上传和下载

不使用缓存机制,自己处理文件的相关逻辑。通过调用父类Request中的setShouldCache(false)方法将一个请求设置为不缓存。默认请求都是可以缓存的。

public final Request<?> setShouldCache(boolean shouldCache) {  }

总 结

Volley的官方文档中附有一张Volley的工作流程图,现在看懂了这张图,上面所讲的内容你算是明白了。

其中蓝色部分代表主线程,绿色部分代表缓存线程,橙色部分代表网络线程。我们在主线程中调用RequestQueue的add()方法来添加一条网络请求,这条请求会先被加入到缓存队列当中,如果发现可以找到相应的缓存结果就直接读取缓存并解析,然后回调给主线程。如果在缓存中没有找到结果,则将这条请 求加入到网络请求队列中,然后处理发送HTTP请求,解析响应结果,写入缓存,并回调主线程。

后 话

1 okhttp
OkHttp 是 Square 公司开源的针对 Java 和 Android 程序,封装的一个高性能 http 请求库,所以它的职责跟 HttpUrlConnection 是一样的,支持 spdy、http 2.0、websocket ,支持同步、异步,而且 OkHttp 又封装了线程池,封装了数据转换,封装了参数使用、错误处理等,api 使用起来更加方便。可以把它理解成是一个封装之后的类似 HttpUrlConnection 的一个东西,但是你在使用的时候仍然需要自己再做一层封装,这样才能像使用一个框架一样更加顺手。

2 Retrofit
Retrofit 是 Square 公司出品的默认基于 OkHttp 封装的一套 RESTful 网络请求框架,不了解 RESTful 概念的不妨去搜索学习下,RESTful 可以说是目前流行的一套 api 设计的风格,并不是标准。Retrofit 的封装可以说是很强大,里面涉及到一堆的设计模式,你可以通过注解直接配置请求,你可以使用不同的 http 客户端,虽然默认是用 http ,可以使用不同 Json Converter 来序列化数据,同时提供对 RxJava 的支持,使用 Retrofit + OkHttp + RxJava + Dagger2 可以说是目前比较潮的一套框架,但是需要有比较高的门槛。

3 Volley VS OkHttp
毫无疑问 Volley 的优势在于封装的更好,而使用 OkHttp 你需要有足够的能力再进行一次封装。而 OkHttp 的优势在于性能更高,因为 OkHttp 基于 NIO 和 Okio ,所以性能上要比 Volley更快。

4 OkHttp VS Retrofit
毫无疑问,Retrofit 默认是基于 OkHttp 而做的封装,这点来说没有可比性,肯定首选 Retrofit。

5 Volley VS Retrofit
这两个库都做了非常不错的封装,但是 Retrofit 解耦的更彻底,尤其 Retrofit 2.0 出来,Jake 对之前 1.0 设计不合理的地方做了大量重构,职责更细分,而且 Retrofit 默认使用 OkHttp ,性能上也要比 Volley 占优势,再有如果你的项目如果采用了 RxJava ,那更该使用 Retrofit 。
目前最流行的网络框架:Retrofit + RxJava

6 总结
所以综上,如果以上三种网络库你都能熟练掌握,那么优先推荐使用 Retrofit ,前提是最好你们的后台 api 也能遵循 RESTful 的风格,其次如果你不想使用或者没能力掌握 Retrofit ,那么推荐使用 Volley ,毕竟 Volley 你不需要做过多的封装,当然如果你们需要上传大数据,那么不建议使用 Volley,否则你该采用 OkHttp 。

Volley网络框架分享相关推荐

  1. Android之对Volley网络框架的一些理解

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/50888340 本文出自:[顾林海的博客] ##前言 Volley这个网 ...

  2. Android 网络编程系列(5)Volley 网络框架入门

    前言 上篇文章中我们对 HttpUrlConnection 的相关用法稍作介绍,可以看到如果不对它进行封装,那么每次使用时就必须写很多重复的代码,并且需要自己创建线程进行网络连接,获取到响应结果后还需 ...

  3. Android网络框架Volley的快速使用

    一.基本使用 之前做Android开发都是使用学长自己封装好的网络请求框架,第三方网络框架也很多,网上搜索了一下,大多数人推荐使用 android-async-http okhttp Volley 其 ...

  4. ym—— Android网络框架Volley(终极篇)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103).谢谢支持! 没看使用过Volley的同学能够,先看看 Android网络框架Volley(体验篇) ...

  5. Google官方网络框架-Volley的使用解析Json以及加载网络图片方法

    Google官方网络框架-Volley的使用解析Json以及加载网络图片方法 Volley是什么?Google I/O 大会上,Google 推出 Volley的一个网络框架Volley适合什么场景? ...

  6. Google官方网络框架Volley实战——QQ吉凶测试,南无阿弥陀佛!

    Google官方网络框架Volley实战--QQ吉凶测试,南无阿弥陀佛! 这次我们用第三方的接口来做一个QQ吉凶的测试项目,代码依然是比较的简单 无图无真相 直接撸代码了,详细解释都已经写在注释里了 ...

  7. Android网络框架Volley项目实战-刘桂林-专题视频课程

    Android网络框架Volley项目实战-5257人已学习 课程介绍         使用Google 2013 I/O大会上发布的Volley请求框架做几个实战项目,归属地查询,QQ测试吉凶,天气 ...

  8. 一个整合OkHttp 、Retrofit 、Volley 、RxJava、Novate多种开源网络框架的项目,高度的封装和集成,Android中Web网络请求一行代码解决

    一个整合OkHttp .Retrofit .Volley .RxJava.Novate多种开源网络框架的项目,高度的封装和集成,Android中Web网络请求一行代码解决 AndroidHttp 一个 ...

  9. 基于OkHttp 、Retrofit 、Volley 、RxJava、Novate多种网络框架整合的快速项目开发框架,一行代码实现Ftp文件上传、文件下载、文件删除和进度监听的工具类的使用

    基于OkHttp .Retrofit .Volley .RxJava.Novate多种网络框架整合的快速项目开发框架,Ftp文件上传.文件下载的工具类的使用. 依赖于Ftp的jar包,对上传.下载.删 ...

最新文章

  1. Eclipse安装反编译插件
  2. 二叉查找树的先序遍历,中序遍历,后序遍历
  3. google+stackoverflow_解决stackOverflow打开慢的问题
  4. TaskAttempt killed because it ran on unusable node IP:8041 Container released on a *lost* node
  5. windows环境的python的环境变量_win的环境变量配置(Python实例)
  6. jquery Datatables 行数据删除、行上升、行下降功能演示
  7. NetSet:一款功能强大的自动化网络流量安全增强工具
  8. wps2019启用宏+excel批量打开网址
  9. [读书笔录]解析卷机神经网络(魏秀参)——第三章
  10. Hook技术第二讲,之虚表HOOK
  11. python股票量化交易从入门到实践df_python股票量化交易从入门到实践df_Python股票量化交易从入门到实践/金融科技系列......
  12. c++17之结构化绑定
  13. 《异度神剑2》与柏拉图的精神世界略考(上)
  14. UE5 Live Coding编译出错时乱码问题解决方法
  15. contiki学习笔记(三)contiki系统
  16. NetLink机制使用
  17. Spring Boot入门(24):Spring Boot事务 | 超级详细,建议收藏
  18. 色环电阻的电阻值大小的确定
  19. [论文阅读] (22)图神经网络及认知推理总结和普及-清华唐杰老师
  20. Linux脚本:Bash脚本看这一篇就够了

热门文章

  1. 福建厦门双十计算机竞赛,厦门双十中学新高三学生 获信息学奥赛金奖保送清华...
  2. 软件及其相关技术发展改变了哪些行业与领域,结合自身体会和理解举例说明。
  3. 【PCL】—超体聚类点云分割算法详解
  4. 云服务器安全组协议,云服务器设置安全组协议
  5. C++类的初始化列表
  6. 菜鸟Docker教程
  7. 【KMRE全新升级】玩法更多、应用更全、体验更好
  8. 2021前端vue面试题(高频)
  9. NiFi HTTPS协议下使用REST API
  10. 微信小程序 | 网易云+ChatGPT实现一个智能音乐推荐小程序