Volley网络请求概述


特点:

· 自动调度网络请求

· 支持并发网络连接(即支持多线程)

· 支持标准的HTTP缓存协议(由服务器来决定是否缓存数据)

· 支持请求优先级设置(4级)

· 支持取消单个或多个请求

· 易于定制(重试),扩展性强。比如Retry&Backoff机制

· 强大的网络请求能力让你轻松的发送异步请求来填充UI数据

· 提供调试和跟踪工具

优点:

擅长将RPC(远程过程调用协议,C/S模式)类型的操作,用来展示服务器数据。比如以某种数据格式获取一页搜索结果。支持任意的数据传输格式,比如图片,字符串,json,你也可以定义自己的数据格式。其实就是自定义Request。Volley让你不再写这些重复的模板代码(网络请求逻辑,不再重复造轮子),这样你就可以专注于你应用本身的业务逻辑.

缺点:

由于Volley都是在内存中解析和处理数据,所以不适合大数据量的下载操作。如果需要下载大文件,可以考虑使用系统的DownloadManager。

 

Volley使用

1. 直接把代码clone下来,把volley的代码直接copy到你的project里,

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

2. 作为一个library项目存在或者jar包存在

 

3. 添加网络权限

发送一个简单的请求

步骤:

       1. 初始化一个RequestQueue

            mRequestQueue = Volley.newRequestQueue(this);

       2. 构建一个Request,这个Demo里我们使用的是StringRequest

             StringRequest request = new StringRequest(

                    要访问的URL,

                    new Response.Listener() {},//请求结果正确返回的listener

                    new Response.ErrorListener() {});    //请求结果错误返回的lisetner

       3. Request对象添加到RequestQueue

            mRequestQueue.add(request);

Volley网络请求交互流程

当调用add()方法的时候,Volley会运行一个缓存处理线程和一池子网络分发线程。

当添加RequestRequestQueue的时候,请求先被缓存线程处理和鉴别:如果请求在缓存中有,则将缓存的response响应在缓存线程中进行解析并将解析后的响应分发给主线程。

如果缓存中没有这个Request请求,则将这个Request放到网络队列中。第一个可用的网络线程将Request请求从队列中取出来,执行HTTP传输,并在工作线程中解析响应,将响应写进缓存,并将解析好的响应内容传给主线程进行分发。

Volley将像IO、解析等耗时操作都放到了工作线程(子线程)来执行。你可以在任何线程去添加请求,Volley会将响应直接在主线程去进行分发。

 

取消请求

1)取消单个请求

调用Request.cancel()方法。在onStop()方法中调用,因为一旦请求被取消volley会确保你的响应不会被执行,在onStop()方法中执行的话不需要判断getActivity()==null来判断掠过处理结果其他类似onSaveInstanceState()等保护性方法里面也不需要检测。

2)取消多个请求

requestQueue.cancelAll(this)

为每个请求的对象都绑定一个tag对象,使用tag来提供取消的范围。所有请求都绑定到执行的Activity上(以Activitythis作为Requesttag),然后你可以在 onStop() 方法执行 requestQueue.cancelAll(this) 来取消这些请求。同样的,你可以为ViewPager中的所有请求图片的Request对象分别打上对应Tabtag。并在滑动时取消这些请求,用来确保新生成的tab不会被前面tab的请求任务阻塞。

RequestQueue源码解析

我们是通过Volley.newRequestQueue”方法来获取RequestQueue的实例的,Volley先构建了BasicNetworkDiskBasedCache,然后将这两个对象作为参数传递给了RequestQueue,构建出了RequestQueue对象。紧接着,调用了RequestQueue.start()方法,开启了消息队列。

2.3之后HTTPURLConnection更适合安卓:因为它的API更简单,包更小,支持网络缓存,提高了速度节省电量。

更易于定制:底层可以定制自己想要的方法实现网络请求。

RequestQueue.start()”中,我们先在start之前进行了stop操作,然后先后构建了缓存线程CacheDispatcher和网络线程NetworkDispatcher,并将它们开启了。

CacheDispatcherNetworkDispatcher是线程,是因为它们实际上都是Thread的子类,因此,调用CacheDispatcher或者NetworkDispatcher对象的start()方法,最终关键逻辑一定是走的是run()方法。

 

CacheDispatcher源码解析

1. CacheDispatcher被开启的时候,内部实际上是维护这一个while(true)死循环,不停的从队列中取Request

2. 取到Request之后,判断Request的状态是否是被取消的状态,若被取消,则不做任何处理;

3. Request没有被取消,则看是否有这个Request对应的缓存数据,若没有缓存数据,则将Request添加到网络队列中去;

4. 有缓存数据,则判断缓存数据是否已经过期,若数据过期,则添加Request到网络队列;

5. 若缓存数据没有过期,则将缓存的原始二进制数据解析成对应的Response数据,比如如果请求的是StringRequest就将二进制数据解析成String

6. 将解析好的Response响应分发到主线程,将解析好的Response分发到主线程调用的是“mDelivery.postResponse(request, response);”,而这个mResponsePoster实际上是一个线程池,它重写了自己的execute方法,在execute方法执行时,将对应的Runnable对象借助Handler分发到了主线程去执行,因此,我们的Response响应最终会在主线程被调用方接收并进行处理。

NetworkDispatcher源码解析

1. NetworkDispatcher被开启的时候,内部实际上是维护这一个while(true)死循环,不停的从队列中取Request

2. 取到Request之后,判断Request的状态是否是被取消的状态,若被取消,则不做任何处理;

3. Request没有被取消,则根据Request去执行网络请求,获取响应Response

4. 将响应的原始二进制数据解析成对应的Response数据,比如如果请求的是StringRequest就将二进制数据解析成String

5. 缓存响应的数据Response

6. 将响应的信息分发到主线程

执行网络网络请求,获取Request对应的响应Response,调用的是“mNetwork.performRequest(request)”方法,实际上底层执行的是HurlStack或者HttpClientStack中的performRequest方法。若是执行HurlStackperformRequest方法,则底层其实是调用的HttpURLConnection;若是执行HttpClientStackperformRequest方法,则底层其实是调用的HttpConnection

分发Response到主线程的逻辑与CacheDispatcher中的分发逻辑完全一致。

使用单例来管理RequestQueue

创建一个RequestQueue是非常消耗资源的,在一个Application中只需维护一个RequestQueue的实例就可以了。

在写应用的时候,我们可以采用单例模式来管理RequestQueue的实例,节省资源的开销。

发起一个标准的Volley网络请求

标准的Volley请求有:

StringRequestImageRequestJsonObjectRequest JsonArrayRequest

区别就是new的对象和传的参数不一样

1StringRequest

StringRequest request = new StringRequest(

                    要访问的URL, 

                     new Response.Listener() {},//请求结果正确返回的listener

                     new Response.ErrorListener() {});    //请求结果错误返回的lisetner

2ImageRequest

ImageRequest request = new ImageRequest(

                     要访问的URL, 

                     new Response.Listener() {},    //请求结果正确返回的listener

                     0,         //压缩比,不想压缩就传0

                     0,         //压缩比,不想压缩就传0

                     null,     //伸缩,null不做任何处理

                    Bitmap.Config.RGB_565,     //想让图片显示的质量,RGB_565ARGB_8888ARGB_4444

                     new Response.ErrorListener() {});        //请求结果错误返回的listener

3JsonObjectRequest

JsonObjectRequest request = new JsonObjectRequest(

                     要请求的URL, 

                     params,        //要向服务器传入的参数

                    new Response.Listener() {},      //请求结果正确返回的listener

                    new Response.ErrorListener() {});         //请求结果错误返回的listener

 

4ImageLoader:不使用内存缓存,则给一个默认的ImageCache,不重写里面的方法

 mImageLoader = new ImageLoader(

                mRequestQueue,         //请求队列

               new ImageLoader.ImageCache() {重写getBitmapputBitmap});    //imageloader的缓存在普通缓存前执行

        使用ImageLoader加载图片

        mImageLoader.get(

                    URL,     //要请求图片的地址

                    ImageLoader.getImageListener(

                                mIv,        //显示到哪

                                R.mipmap.ic_launcher,     //默认显示图片的资源id

                                R.mipmap.ic_launcher)    //请求失败显示的图片

                    );

5NetworkImageView:加载网络图片 

在布局文件中:

       

            android:id="@+id/niv"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_centerInParent="true" />

在代码中(前两步跟ImageLoader一样,最后一步如下):

        mNiv.setImageUrl(URL, mImageLoader);

 

自定义request

自定义Request需要实现两步:

       1. 继承Request,其中T表示转换成的Response的类型

       2. 实现抽象方法 parseNetworkResponse()  deliverResponse()


 

 

 

你可能感兴趣的:(Volley网络请求概述)