【进阶android】Volley源码分析——Volley的流程
来源:互联网 发布:微信破解密码软件 编辑:程序博客网 时间:2024/06/05 09:11
本文章开始分析Volley的具体源代码了;首先介绍Volley的总体流程,文章总体分为三个部分:Request类的分析、RequestQueen类的分析以及Volley的总体流程。
一、Request类
Volley框架之中,Request是对一次网络请求流程的抽象;从发起请求、获取响应、解析响应、传递响应都属于Request的范畴之中。
而Request类中一共有16个的属性,一个接口,一个枚举;可以将其分为以下三类:
1、用于描述Request自身状态的属性;主要为以下几个属性:
2、用以描述请求的属性:
3、响应相关的属性:
剩下的5个属性之中,有4个属性是和日志(logcat)相关的,余下的一个属性较为重要,其类别为RequestQueue,引用了一个RequestQueue对象。我们将在后面详细介绍该类。
至此,我们便介绍完Request类中主要的属性;其中需要补充说明的是Response类中除了有一个错误监听器之外(ErrorListener),还有一个普通的正常监听器(Listener)该监听器为一个正常解析了响应的回调接口。Request类中并没有该正常监听器的引用,这是因为Request类是一个抽象类,它将这一部分的工作下放给它的子类了。
最后对于Cache.Entry这个属性做一个说明,Cache是一个接口,是对整个Volley中的内存缓存机制做了一个抽象;Volley中的内存缓存默认是一个集合,Cache接口主要抽象了对这个集合的操作,例如初始化、增加缓存、获取缓存等等,而Cache.Entry就是内存缓存之中的一个元素(实体),具体将在【进阶android】Volley源码分析——Volley的缓存这篇文章之中分析。
Request类中有两个方法较为重要,一个是parseNetworkResponse方法;一个是deliverResponse方法;这两个方法都是抽象方法,需要其子类进行个性化重写,parseNetworkResponse方法主要是将HTTP响应解析生成一个Response<T>对象;deliverResponse方法则主要是由主线程调用,负责主线程对响应的处理。
至此,Request的主要属性和方法则介绍完成;上文曾提过,一个Request对象是一次网络请求流程的抽象;当要进行一次网络请求时,首先需要知道请求的URL,根据URL构造一个Request对象,接着会结合一个RequestQueue对象进行一次网络请求,网络请求成功,则将响应通过Request对象的parseNetworkResponse方法生成一个Response对象,然后再讲Request及其对应的Response封装为一个消息,传递给主线程,主线程调用Request对象的deliverResponse方法来执行对响应的处理,例如根据响应结果更新UI等等。其中构造一个Request对象、调用deliverResponse方法等是在主线程之中执行的;网络请求,解析Response等操作则是在网络线程之中执行的。
这就是整个Volley中一次网络请求的总体流程。由此可以看出Volley对网络请求中的具体功能(HTTP如何通信)几乎未做相关优化,只是把网络请求之前和网络请求之后的工作进行了相应的优化,使之更加适用于Android模式,例如网络线程与主线程的通信皆是采用的Handler机制。当然,真正的Volley框架还会在这个基础流程之上加入缓存机制。
下面我们看看RequestQueue类。
二、RequestQueue类
做过Android开发的程序员应该都知道,Android的UI线程即主线程,并不允许进行网络请求的操作(会报出一个NetworkOnMainThreadException异常),因为网络请求本身就是一个耗时的操作,要进行网络请求,一个较好的方法则是使用子线程。基于此,Volley大部分的工作并非在主线程上完成的,对于主线程它只是提供了响应的一些接口来执行,例如Response类中的ErrorListener接口和Listener接口皆是Volley提供给主线程处理的接口,这两个接口一个是处理请求失败的情况,一个是处理请求成功的情况。
默认情况下,Volley会除主线程外,开启5个子线程(主线程并不是Volley开启的,这是一个常识),5个子线程中有4个网络线程,主要处理网络请求,一个缓存线程,主要处理缓存请求。而对这5个线程的管理则交由RequestQueue负责了。
总体而言,RequestQueue有两个主要的功能,一个功能就如它的名字,用来管理Request的队列;另一个功能则是用来开启、停止这五个子线程。
RequestQueue主要有9个比较重要的属性分别如下:
以上便是对RequestQueue属性的大致分析;而在RequestQueue方法之中,本章主要分析start()方法和add(Request request)方法;因为对于整个Volley框架而言,这两个方法对整个框架的流程而言,都至关重要。
两个方法的逻辑并不复杂,但是Volley框架的运行离不开这两个方法;两个方法都是由主线程调用,其中start方法主要开启RequestQueue对应的5个线程,及初始化4个NetworkDispatcher对象及1个CacheDispatcher对象,这5个对象都是Thread对象的子对象,5个子线程对应的处理逻辑我们将在【进阶android】Volley源码分析——Volley的线程一文中详细分析。
<pre name="code" class="java">public void start() { // Make sure any currently running dispatchers are stopped. //确保当前所有运行的子线程线程都要被停止 stop(); // Create the cache dispatcher and start it. //创建一个缓存调度器,并运行其对应的线程 mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery); mCacheDispatcher.start(); // Create network dispatchers (and corresponding threads) up to the pool size. //创建制定个数的网络调度器,运行相应的子线程 for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); } }
public Request add(Request request) { // Tag the request as belonging to this queue and add it to the set of current requests. request.setRequestQueue(this);//将该RequestQueue对象映射到Request对象之中 synchronized (mCurrentRequests) { mCurrentRequests.add(request);//添加到总队列之中 } // Process requests in the order they are added. request.setSequence(getSequenceNumber());//生成请求唯一码 request.addMarker("add-to-queue"); // If the request is uncacheable, skip the cache queue and go straight to the network. if (!request.shouldCache()) {//如果该请求不用缓存,则添加到需要网络线程处理的列表之中,并返回 mNetworkQueue.add(request); return request; } // Insert request into stage if there's already a request with the same cache key in flight. synchronized (mWaitingRequests) { String cacheKey = request.getCacheKey();//Request的缓存key就是该Request对象对应的URL if (mWaitingRequests.containsKey(cacheKey)) {//该请求是否存在重复请求 // There is already a request in flight. Queue up. Queue<Request> stagedRequests = mWaitingRequests.get(cacheKey); if (stagedRequests == null) { stagedRequests = new LinkedList<Request>(); } stagedRequests.add(request);//如果存在则将该请求添加到等待队列之中 mWaitingRequests.put(cacheKey, stagedRequests); if (VolleyLog.DEBUG) { VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey); } } else { // Insert 'null' queue for this cacheKey, indicating there is now a request in // flight. mWaitingRequests.put(cacheKey, null); mCacheQueue.add(request);//如果不存在则直接将该Request对象添加缓存线程处理的队列之中 } return request; } }根据以上代码,我们可以分析出add方法的流程如下:
- 【进阶android】Volley源码分析——Volley的流程
- 【进阶android】Volley源码分析——Volley的线程
- 【进阶android】Volley源码分析——Volley的缓存
- 【进阶android】Volley源码分析——Volley的工具【StringRequest】
- 【进阶android】Volley源码分析——Volley的工具【ImageLoader】
- 【进阶android】Volley源码分析——总述
- Volley源码流程分析
- android Volley的源码分析
- Android——volley源码分析
- Android-Volley源码分析
- [Android]volley源码分析
- Android-Volley源码分析
- android Volley 源码分析
- Volley源码及流程分析
- Volley的源码分析
- android-----Volley框架源码分析
- android-----Volley框架源码分析
- Android Volley源码分析(1)
- 配置核查模块 开发总结 (1)
- L 预置apk
- 判断一个数字中是否包含两个相同的字串
- Avoiding duplicate symbol errors during linking by removing classes from static libraries
- 防止按钮在短时间被连续点击
- 【进阶android】Volley源码分析——Volley的流程
- windows bat脚本编写
- struts2上传
- 极客班GeekBand - 互联网思维修炼 - 1
- 创业公司如何公平分配股权?
- 简单选择排序算法原理及JAVA实现
- 为什么匿名内部类访问当前方法的局部变量必须为final类型
- 南阳 oj 兰州烧饼
- Struts2 vs SpringMVC for Me