Android-volley

推荐阅读:

Android 异步网络请求框架-Volley

Volley全方位解析,带你从源码的角度彻底理解

Volley 是 Google 推出的轻量级 Android 异步网络请求框架和图片加载框架。在 Google I/O 2013 大会上发布。其适用场景是数据量小,通信频繁的网络操作。

主要特点:
(1). 扩展性强。Volley 中大多是基于接口的设计,可配置性强。
(2). 一定程度符合 Http 规范,包括返回 ResponseCode(2xx、3xx、4xx、5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。
(3). 默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现。
HttpURLConnection 和 AndroidHttpClient(HttpClient 的封装)如何选择及原因:
在 Froyo(2.2) 之前,HttpURLConnection 有个重大 Bug,调用 close() 函数会影响连接池,导致连接复用失效,所以在 Froyo 之前使用 HttpURLConnection 需要关闭 keepAlive。另外在 Gingerbread(2.3) HttpURLConnection 默认开启了 gzip 压缩,提高了 HTTPS 的性能,Ice Cream Sandwich(4.0) HttpURLConnection 支持了请求结果缓存。再加上 HttpURLConnection 本身 API 相对简单,所以对 Android 来说,在 2.3 之后建议使用 HttpURLConnection,之前建议使用 AndroidHttpClient。
(4). 提供简便的图片加载工具。

如上官方给出的Volley架构图,蓝色为主线程,绿色为缓存线程,橙色是网络线程。
总的来说,就是一个请求队列和三种线程,UI线程(1个),Cache线程(1个)和Network线程(默认是4个)。

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

Volley到底有哪些特点呢?

自动调度网络请求,异步,不用我们控制线程
多个并发的网络连接
通过使用标准的HTTP缓存机制保持磁盘和内存响应的一致
支持请求优先级,网络请求的排序(scheduling)
支持取消请求的强大API,可以取消单个请求或多个,多级别取消请求
易于定制
健壮性:便于正确的更新UI和获取数据
包含调试和追踪工具
和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)
请求的缓存

上面是 Volley 的总体设计图,主要是通过两种Dispatch Thread不断从RequestQueue中取出请求,根据是否已缓存调用Cache或Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据,然后交由ResponseDelivery去做结果分发及回调处理。

Volley 请求流程图:

类关系图:

这是 Volley 框架的主要类关系图
图中红色圈内的部分,组成了 Volley 框架的核心,围绕 RequestQueue 类,将各个功能点以组合的方式结合在了一起。各个功能点也都是以接口或者抽象类的形式提供。
红色圈外面的部分,在 Volley 源码中放在了 toolbox 包中,作为 Volley 为各个功能点提供的默认的具体实现。
通过类图我们看出, Volley 有着非常好的拓展性。通过各个功能点的接口,我们可以给出自定义的,更符合我们需求的具体实现。

简介:

Google I/O 2013 大会上发布的 Android 异步网络请求框架和图片加载框架。

试用场景:适合数据量小,通信频繁的网络操作。

注意事项

Volley 适合于数据量小的并发请求,因为在数据请求完成后,会将请求得到的数据读到内存中存放在byte[],然后分发给调用者进行数据的转换。若用volley请求大数据则可能会OOM。

Volley的线程池不具备伸缩功能,创建后所有线程均处于启用状态,不支持动态调整。

  1. 兼容性好:默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现 (android 2.3以下HttpURLConnection有严重bug)
  2. 提供了取消Http 请求的接口,在Activity关闭但是仍旧执行的Http请求可以及时销毁,减少了性能的开销以及Activity能够及时回收。
  3. 使用了多线程(默认4个线程)+ 请求队列的形式,而不是每次请求都单独开启一个线程,减少了性能的开销。
  4. 支持缓存:在Http协议层(在进行条件请求时,客户端会提供给服务器一个If-Modified-Since请求头,其值为服务器上次返回的Last-Modified响应头中的日期值, 服务器会读取到这两个请求头中的值,判断出客户端缓存的资源是否是最新的,如果是的话,服务器就会返回HTTP/304 Not Modified响应)和客户端都支持cache,大大减少了服务器压力。同时对客户端性能开销也会有一定的减少。
  5. 避免同一个http请求多次连接服务器:如果某个请求已经在等待队列,并且该请求允许缓存,将该请求放到等待队列中,使得URI一致的请求不会重复去请求服务器.
  6. 从框架本身的角度来说,Request接口、Cache接口、HttpStack等都是以接口的形式来定义的,充分地展示了Java中面向接口编程的特点,使得代码的扩展性大大增强

Volley中的RequestQueue 和 Request

RequestQueue 	用来执行请求的请求队列
Request 	用来构造一个请求对象

Request		对象主要有以下几种类型: 
		StringRequest 		响应的主体为字符串
		JsonArrayRequest 		发送和接收JSON数组
		JsonObjectRequest 		发送和接收JSON对象
		ImageRequest 		发送和接收Image

Volley的基本使用

volley使用及其简单,我们只需要创建一个RequestQueue请求队列,然后往队列里面扔http请求即可,volley会
不断从队列里面取出请求然后交给一堆工作线程处理。这里的http请求是通过Request类来封装的,我们只用创建Request对象,然后提供诸如url之类的参数即可。网络操作全部是在子线程中处理的,我们不必担心阻塞UI线程。

网络请求的结果会异步返回给我们,我们只需要处理Request的回调即可。

Request本身是一个抽象类,不能直接创建实例,volley为我们实现了一些Request,比如StringRequest是普通http请求,JsonRequest可以封装json数据,并将服务端的返回数据封装成JsonObject,ImageRequest可以请求一张网络图片,并将服务端的返回数据封装成Bitmap。

Request的使用分为三步:
1.创建RequestQueue队列;
2.创建Request对象,并加入队列中;
3.处理回调事件。

1、创建一个RequestQueue requestQueue,

RequestQueue requestQueue=Volley.newRequestQueue(this);//这里的this指的是Context

2、构建一个自己所需要的XXRequest req,


private final String url="http:/xxxxx"//所需url
    JsonObjectRequest req=new JsonObjectRequest(url,null,new Response.Listener<JsonObject>(){
        @Override
        public void onResponse(JsonObject response){
            //添加自己的响应逻辑,//此处为主线程
        }
    },
    new ResponseError.Listener(){
        @Override
        public void onResponseError(VollerError error){
            //错误处理
            L.d("Error Message:","Error is"+error);
        }
    });

3、通过requestQueue.add(req);将请求添加至请求队列;

关于volley请求失败会重新请求问题

Volley中没有指定的方法来设置请求超时时间,可以设置RetryPolicy 来变通实现。DefaultRetryPolicy类有个initialTimeout参数,可以设置超时时间。要确保最大重试次数为0,以保证超时后不重新请求。

//重试不请求
  stringRequest.setRetryPolicy(new DefaultRetryPolicy(
				20 * 1000,// 默认超时时间,应设置一个稍微大点儿的如20秒,Volley默认2.5秒
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,// 默认最大尝试次数 : 1
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));//默认超时时间的乘积因子 :1.0f



   /**
     * Volley默认的超时时间(2.5s)
     * HttpClient的默认超时时间,也就是10000ms.即10秒
     */
    public static final int DEFAULT_TIMEOUT_MS = 2500;



    /**
     * Volley默认的重试次数(1次)
     */
    public static final int DEFAULT_MAX_RETRIES = 1;



    /**
     * Volley默认超时时间的乘积因子.
     * 以默认超时时间为2.5s为例:
     * 1. DEFAULT_BACKOFF_MULT = 1f, 则每次HttpUrlConnection设置的超时时间都是2.5s*1f*mCurrentRetryCount.
     * 2. DEFAULT_BACKOFF_MULT = 2f, 则第二次超时时间为:2.5s+2.5s*2=7.5s,第三次超时时间为:7.5s+7.5s*2=22.5s
     */
    public static final float DEFAULT_BACKOFF_MULT = 1f;


    /**
     * 开发者自定制Request重试策略构造函数
     *
     * @param initialTimeoutMs  超时时间
     * @param maxNumRetries     最大重试次数
     * @param backoffMultiplier 超时时间乘积因子
     */
    public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
        mCurrentTimeoutMs = initialTimeoutMs;
        mMaxNumRetries = maxNumRetries;
        mBackoffMultiplier = backoffMultiplier;
    }

关于请求的取消:

在activity的onStop方法中取消所有请求:

@Override  
protected void onStop() {  
    // TODO Auto-generated method stub  
    super.onStop();  
    mRequestQueue.cancelAll(this);  
}  

参考:

Volley 异步网络请求分析
Android网络框架Volley
volley3 网络请求的取消
网络通信框架Volley使用详细说明
Volley超时重试机制详解
在Android中使用Volley进行异步HTTP请求

重试策略

要弄明白超时重试策略首先明白两个异常信息:

java.net.SocketTimeoutException

[code]This exception is thrown when a timeout expired on a socket read or accept operation.

当读取一个socket或者接受操作超时会抛出该异常,通俗讲就是响应超时。

org.apache.http.conn.ConnectTimeoutException

[code]A timeout while connecting to an HTTP server or waiting for an available connection from an HttpConnectionManager.

当连接HTTP服务或者从HttpConnectionManager中得到一个可用的连接超时后抛出该异常,通俗讲就是请求超时。

个人对一次http请求的理解为以下三个阶段,一:建立连接;二:数据传送;三,断开连接;

当建立连接在规定的时间内(ConnectionTimeOut)没有完成,那么此次连接就结束,抛出ConnectTimeoutException后续的SocketTimeOutException就一定不会发生。

只有当连接建立起来后,也就是没有发生ConnectionTimeOutException ,才会开始传输数据,如果数据在规定的时间内(SocketTimeOut)传输完毕,则断开连接。否则,触发SocketTimeOutException

每次执行retry后,超时时间会增大,当重试次数大于mMaxNumRetries值后,抛出异常,结束该次请求;

参考:

Volley超时重试策略_RetryPolicy

Volley 内部请求数据的实现方式


  if (Build.VERSION.SDK_INT >= 9) {  
            stack = new HurlStack();//SDK如果大于等于9,也就是Android 2.3以后,
            因为引进了HttpUrlConnection,所以会用一个HurlStack  
        } else {//如果小于9,则是用HttpClient来实现  
            // Prior to Gingerbread, HttpUrlConnection was unreliable.  
            // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html  
            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));  
        }  

Volley内部根据sdk版本来决定使用httpURLconnection还是httpclient:
大于等于9( Android2.3 ):httpURLconnection
小于9( Android2.3 )则:httpclient

Android中关于Volley的使用(五)从RequestQueue开始来深入认识Volley

volley中文乱码问题:

复写这个Volley中Request类的parseNetworkResponse方法

/**
	 * 重写以解决乱码问题
	 */
	@Override
	protected Response<String> parseNetworkResponse(NetworkResponse response) {
		String str = null;
		try {
			str = new String(response.data, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return Response.success(str,
				HttpHeaderParser.parseCacheHeaders(response));
	}

参考:

解决Volley乱码问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值