天天看点

Android:Volley源代码解析

Volley是一个封装HttpUrlConnection和HttpClient的网络通信框架,集AsyncHttpClient和Universal-Image-Loader的长处于了一身。既能够像AsyncHttpClient一样很easy地进行HTTP通信,也能够像Universal-Image-Loader一样轻松载入并缓存下载的图片。Volley在性能方面也进行了大幅度的调整,它的设计目标就是进行<code>数据量不大,但通信频繁的网络操作</code>,而对于大数据量的网络操作,比方说下载文件等,Volley的表现就会比較糟糕。从以下这个简单的实例来研究一下源代码。

RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);

首先看一下RequestQueue这个类:

从构造函数可知,mWaitingRequests、mCurrentRequests、mCacheQueue、mNetworkQueue是以组合形式实例化,后两者是堵塞队列;而mCache、mNetwork是以聚合形式注入;mDelivery默认也是组合形式<code>new ExecutorDelivery(new Handler(Looper.getMainLooper())))</code>实例化。

newRequestQueue方法:

结合RequestQueue类可知,实例化的RequestQueue对象,注入了<code>new DiskBasedCache(cacheDir)</code>和<code>network1</code>。缓存方式默认是磁盘缓存。NetWork对象会依据系统版本号。选用不同的Http通信方式。

queue.start()方法

CacheDispatcher和NetworkDispatcher都是继承Thread类。所以这种方法生成一条缓存分发线程,和四条网络线程。

CacheDispatcher类继承Thread类。全部參数都是聚合形式注入,看下关键的run()方法。因为代码较长。这里不贴了,分段分析下几个比較重要的方法

首先任务是一个死循环,因为mCacheQueue是个堵塞队列,所以将不断地从堵塞队列读取Request

推断请求是否有缓存。<code>假设没有或者缓存已经过期。将请求放到网络队列里面</code>。否则找到缓存。则进行以下的操作。

parseNetworkResponse是Request类的抽象方法,我们进去StringRequest看下:

可看作是对网络下载的数据进行解析处理。然后返回。

最后进行这一步,mDelivery是在RequestQueue里面实例化后注入CacheDispatcher的。详细的实例化对象:new ExecutorDelivery(new Handler(Looper.getMainLooper()))。看下ExecutorDelivery类。找到postResponse方法。

&gt; request, Response&lt;?

<code>&gt; response, Runnable runnable) { ... this.mResponsePoster.execute(new ExecutorDelivery.ResponseDeliveryRunnable(request, response, runnable)); }</code>

继续往下看

deliverResponse方法相同是Request类的抽象方法,我们进去StringRequest看下

就一句回调

NetworkDispatcher类相同继承Thread类,其分析过程和CacheDispatcher差点儿相同,重要的相同是以下几步:

1、从网络堵塞队列读取请求,request = (Request)this.mQueue.take();

2、网络下载,NetworkResponse e = this.mNetwork.performRequest(request);(假设是CacheDispatcher这一步就是缓存推断)

3、处理下载后的数据,Response response = request.parseNetworkResponse(e);

3、对处理后的数据进行回调,this.mDelivery.postResponse(e, response)。

StringRequest stringRequest = new StringRequest (url,listener,errorListener);

由第一个分析步骤能够知道,这个Request主要就是进行两个操作,也就是重写两个方法。

<code>protected abstract Response&lt;T&gt; parseNetworkResponse(NetworkResponse var1);</code>对下载后的数据进行解析处理。

<code>protected abstract void deliverResponse(T var1);</code>最后回调操作这个数据的方法。

所以构造函数仅需下载地址和回调操作的方法。

假设不须要缓存就直接加入到网络队列里面,Request有个比較重要的布尔字段mShouldCache,默认是用来推断是否要进行磁盘缓存的。

否则将其加入到缓存队列,这种方法上面也会进行一些当前队列和等待队列的防反复的操作。

Android:Volley源代码解析

框架部分:

1、实例化一个RequestQueue对象,开启一条缓存线程和默认的四条网络线程,线程不断地从缓存堵塞队列和网络堵塞队列里面读取请求;

2、假设缓存线程从缓存队列里面读取的请求已经缓存过,则解析数据回调操作方法。否则将其加入到网络队列;

3、假设缓存线程从缓存队列里面读取的请求没有缓存过,则加入到网络队列。

4、网络线程从网络堵塞队列不断读取请求,读到请求后则由封装好的HttpStack对象进行网络下载处理、下载后回调对数据处理的方法,处理后回调操作数据的方法。

客户部分:

1、实例化一个请求对象。在请求对象里面重写处理网络下载后的数据的方法。和操作处理后的数据的方法。

2、将请求对象加入到请求队列。请求须要缓存则会被加入到分配到缓存队列,不须要则被加入到网络队列。

之前看过一个问题。说框架和库有什么不同,高人答曰:框架是他调用你代码,库是你调用他代码。

优秀的框架拓展性是如此之强,尽管自己远没那个能力,只是也算开了眼界!