【Android】Volley技术细节简介

一 Volley网络请求流程介绍

  1. 发送请求
    普通的http请求只要创建一个Request对象,然后添加到RequestQueue队列中就可以了。
    Request对象是Volley框架中的一个抽象类,Volley中也提供了几个默认的实现类,如:ImageRequest、JsonRequest (JsonArrayRequest和JsonObjectRequest)、StringRequest。
    从名字定义就可以看出具体的请求用途,下面会对这些内部实现做讲解。
    将Request对象添加到一个RequestQueue对象中就可以了,RequestQueue创建启动后就会循环的遍历Queue队列,如果有请求就会调用执行,否则阻塞等待。RequestQueue的内部实现下面会介绍。
    从应用层面上就是这么简单,其实框架内部还会对请求的缓存,重复请求等有一定处理机制,后面都会介绍。

  2. 请求响应
    Request对象的实现类需要继承parseNetworkResponse接口,该接口会在NetworkDispatcher获取到返回后调用。Request实现类只要在该接口处理返回的数据即可,比如json解析,图片解析以及文件解析等。

  3. BasicNetwork 网络请求过程中,如果遇到网络错误,会根据 RetryPolicy 进行重试。
    在这里插入图片描述

二 Volley主要机制

对于网络框架本身的代码不是很多,结构也很简单,与其它的网络框架如retrofit相比很容易看懂,其内部几个重要的机制:

  1. 任务分发
    任务分发使用RequestQueue负责的,RequestQueue被创建并启动后,会创建一个CacheDispatcher以及线程池最大线程数的NetworkDispatcher(默认是4个线程)。
    CacheDispatcher和NetworkDispatcher继承Thread;首先看一下NetworkDispatcher的构造函数,需要传入BlockingQueue、Network、Cache、ResponseDelivery几个参数,
    这些参数都是从RequestQueue中传入的,需要说明的是BlockingQueue对应的RequestQueue中的NetworkQueue,这是新任务队列,这就让Dispatcher和RequestQueue之间绑定了联系。
    RequestQueue从名字定义来看就是一个队列,它内部有两个队列,一个缓存队列,一个请求队列,他其实是管理这些任务队列的,RequestQueue启动后,Dispatcher线程也都全部启动,NetworkDispatcher执行后便开始从NetworkQueue中获取任务并执行,如果需要缓存,则添加到缓存中,默认的实现是根据设置Request的sholdCache字段来控制,实际开发中可以修改为根据服务器端接口字段标识来设置是否需要缓存请求结果,比如有的接口不需要缓存,需要每次都要从服务端获取;有的如果缓存有数据就直接使用缓存数据;有的则先去请求网络缓存,如果有变化则修改缓存并返回新结果。

  2. 缓存
    Volley中的缓存用于支持缓存的服务器请求,当Request.Mode允许缓存时,默认先添加到缓存队列,如果Cache缓存中没有对应的数据,则添加到NetworkQueue队列中,作为新请求执行。
    再看一下CacheDispatcher的构造函数BlockingQueue(CacheQueue)、BlockingQueue(NetworkQueue)、Cache、ResponseDelivery。它同时关联两个队列。
    实际开发中可以对是否需要缓存,可以自定义缓存策略,只需要对shouldCache()使用的地方做修改即可。如果对Volley队列添加等待队列的话,对于同一请求的等待,如果是优先访问缓存的接口,在该请求正在执行的Request返回后,可将该请求的等待队列清空,并添加到CacheDispatcher中,返回缓存结果,在下面的扩展中将详细介绍。

  3. 线程池
    Volley中的线程池并不是指java的ThreadPoolExecutor对象,而是RequestQueue内部管理的一个CacheDispatcher对象以及N个NetworkDispatcher对象。至于这里是否可以优化,个人感觉可以优化的。在RequestQueue调用Start方法后这些线程对象会被创建并start开始工作。Dispatcher的stop接口会调用interrupt停止对应的线程结束。
    所以Volley的线程池管理没什么可讲的。

  4. 网络连接方式以及错误机制
    Volley中使用HttpUrlConnection和HttpClient,也可以自行扩展比如使用OkHttp等,只要继承HttpStack接口即可,在Android4.4后已经废弃了HttpClient的使用方式了,那默认的也就是HttpUrlConnection对象了。如果对HttpUrlConnection使用不熟悉的那就网上学习一下,简单的描述就是创建http连接,然后得到InputStream,然后解析InputStream获取的数据,主要的不同就是返回的Http数据的不同需要不同的解析器解析内容,比如纯文本、json格式、文件等,对于ImageVolley已经封装了对应的Request对象,对自动对图片资源进行处理;还有就是StringRequest等,开发过程中api的请求主要基于JSON格式的,所以一般会自定义JSON的request。
    错误机制
    根据HttpUrlConnection的连接状态会返回连接过程中的状态,也可以在对应HttpStack实现类中自行添加业务需要的状态,默认的只会返回HttpUrlConnection中定义的错误状态码。
    首先连接状态,当返回非200的状态就需要判断是什么连接错误,是否需要重定向还是重连接;
    返回200说明连接成功,则可以通过connection获取InputStream来获取业务数据或文件;
    返回小于200大于299的错误,就是非成功的错误码,会在BasicNetwork. performRequest抛出IOException异常,然后在异常catch中对各个常见的错误码做处理;
    关于超时:在connection连接的时候会将Request设置的超时时间设置到connection对象中,连接超时和读取超时设置一样也可单独设置,在connection发起connect的时候如果超时了HttpUrlConnection会抛出超时异常,所以BasicNetwork会在performequest里捕获 SocketTimeoutException。
    协议异常:MalformedURLException,在url创建过程中会对protocol校验,对于非法协议会抛出这个异常,比如端口号<-1;或者系统的协议列表中保持的URLStreamHandler对象不存在等。

  5. 可扩展
    对http协议头的扩展:通过Request接口的addHeader方法可以添加协议头;
    对Response响应的扩展:通过实现Requst的parseNetworkResponse接口处理返回信息;
    对请求队列的扩展(等待队列)
    对文件下载上传的扩展(待更新)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值