Volley框架解析



Volley框架解析

     Volley Google 推出的Android异步网络请求框架和图片加载框架,它既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。特别适合数据量小,通信频繁的网络操作,而对于大数据量的网络操作,比如说下载大量的文件等,Volley的表现就不好了,可以使用DownloadManager  

Volley的主要特点

1)扩展性强。Volley 中大多是基于接口的设计,可配置性强。

2 一定程度符合 Http 规范,包括返回ResponseCode(2xx3xx4xx5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。

3)默认 AndroidAndroid 2.2版本之前,HttpClient拥有较少的bugAPI众多,而且实现比较稳定,因此使用它是最好的选择。而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。2.3 及以上基于 HttpURLConnection2.3 以下基于 HttpClient 实现,

4)提供简便的图片加载工具。

它提供ImageLoader加载图片,明显要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求,从源码中看到他的使用过程如下:

a. 创建一个RequestQueue对象。

b. 创建一个ImageLoader对象。

c. 获取一个ImageListener对象。

d. 调用ImageLoaderget()方法加载网络上的图片。

Volley架构图

Volley原理图

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

Volley类图

Volley使用

1.使用前要在AndroidManifesr.xml中配置使用权限<uses-permission android:name="android.permission.INTERNET" />

2.可以从git上下载

git clone https://android.googlesource.com/platform/frameworks/volley

或者下载Volley.jar包,并导入Add As Library

也可以在build.gradle文件中添加依赖:
compile 'com.android.volley:volley:1.0.0'

3. (1)创建RequestQueue对象

  (2)创建xxRequest请求对象

  (3)xxRequest请求对象加入RequestQueue对象中,使用示例如下:

   public void getHomePageData(Context context, final VolleyCallback callback) {

        String jsonUrl = RPCRequestManager.generateJsonUrl(typeURL, path).trim();

       RequestQueue mRequestQueue = Volley.newRequestQueue(context);

        JsonObjectRequest req = new JsonObjectRequest(jsonUrl, null,

                new Response.Listener<JSONObject>() {

                    @Override

                    public void onResponse(JSONObject response) {

               }

                }, new Response.ErrorListener() {

            @Override

            public void onErrorResponse(VolleyError error) {

                VolleyLog.e("Error: ", error.getMessage());

            }

        });

        req.setShouldCache(false);

        mRequestQueue.add(req);

    }

 

Volley源码

网络操作全部是在子线程中处理的,我们不必担心阻塞UI线程。网络请求的结果会异步返回给我们,我们只需要处理Request的回调即可。我们从源码中看网络请求的处理:

Volley.class中,

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.11.50.png

在第39行判断如果stack是等于null的,则去创建一个HttpStack对象,这里会判断如果手机系统版本号是大于9的,则创建一个HurlStack的实例,否则就创建一个HttpClientStack的实例。实际上HurlStack的内部就是使用HttpURLConnection进行网络通讯的,而HttpClientStack的内部则是使用HttpClient进行网络通讯的,创建好了HttpStack之后,接下来又创建了一个Network对象,它是用于根据传入的HttpStack对象来处理网络请求的,紧接着new出一个RequestQueue对象,并调用它的start()方法进行启动,然后将RequestQueue返回。跟踪start,进入RequestQueue.class:
Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.18.33.png
先创建了一个CacheDispatcher的实例,然后调用了它的start()方法,接着在一个for循环里去创建NetworkDispatcher的实例,并分别调用它们的start()方法。这里的CacheDispatcherNetworkDispatcher都是继承自Thread的,而默认情况下for循环会执行四次,也就是说当调用了Volley.newRequestQueue(context)之后,就会有五个线程一直在后台运行,不断等待网络请求的到来,其中CacheDispatcher是缓存线程,NetworkDispatcher是网络请求线程。得到了RequestQueue之后,我们只需要构建出相应的Request,然后调用RequestQueueadd()方法将Request传入就可以完成网络请求操作了,同类下的add()方法中

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.26.37.png

在第131行的时候会判断当前的请求是否可以缓存,如果不能缓存则在第132行直接将这条请求加入网络请求队列,可以缓存的话则在第151行将这条请求加入缓存队列。在默认情况下,每条请求都是可以缓存的,我们也可以调用RequestsetShouldCache(false)方法来改变这一默认行为。既然默认每条请求都是可以缓存的,被添加到了缓存队列中,于是一直在后台等待的缓存线程就要开始运行,进入到CacheDispatcher中的run()方法,

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.35.16.png

52行中while(true)死循环,说明网络请求线程也是在不断运行的在第71行的时候会调用NetworkperformRequest()方法来去发送网络请求,而Network是一个接口,这里具体的实现是BasicNetwork,看下它的performRequest()方法,

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.40.53.png

NetworkDispatcher中收到了NetworkResponse这个返回值后又会调用RequestparseNetworkResponse()方法来解析NetworkResponse中的数据,以及将数据写入到缓存,这个方法的实现是交给Request的子类来完成的,因为不同种类的Request解析的方式也肯定不同。在解析完了NetworkResponse中的数据之后,又会调用ExecutorDeliverypostResponse()方法来回调解析出的数据,

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.44.44.png

mResponsePosterexecute()方法中传入了一个ResponseDeliveryRunnable对象,就可以保证该对象中的run()方法就是在主线程当中运行的。

Macintosh HD:Users:xch:Desktop:屏幕快照 2016-08-04 下午3.45.58.png 

其中在第62行调用了RequestdeliverResponse()方法,每一条网络请求的响应都是回调到这个方法中,最后我们再在这个方法中将响应的数据回调到Response.ListeneronResponse()方法中就可以了。

RequestQueue

顾名思义,它是一个请求队列,并发地发出这些请求,因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,xxRequest提供三参数和四参数的构造函数,对三参数的构造函数,第一个参数就是目标服务器的URL地址,第二个参数是服务器响应成功的回调,第三个参数是服务器响应失败的回调。在四参数的构造函数中,可以设置请求类型:postget,默认是get请求。将xxRequest对象添加到RequestQueue里面。当HTTP通信完成之后,服务器响应的数据信息就会回调到onResponse()方法中,parseNetworkResponse()方法是对服务器响应的数据进行解析,其中数据是以字节的形式存放在NetworkResponsedata变量中,将数据取出后组装成一个类型,并传入Responsesuccess()方法中即可。

自定义Request

我们亦可以通过自己定义请求继承自Request类,实现对应的方法即可,就不做过多介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值