Android-volley

来源:互联网 发布:华润网络控股有限公司 编辑:程序博客网 时间:2024/05/22 10:25

推荐阅读:

Android 异步网络请求框架-Volley

如上官方给出的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的基本使用

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乱码问题

原创粉丝点击