Android Volley框架的使用(二)

来源:互联网 发布:dlp数据防泄密 编辑:程序博客网 时间:2024/06/05 05:13

在上一篇文章中介绍了volley框架的特性,如何将volley.jar引入我们的项目,以及volley框架中最常用的两个类 RequestQueue Request基本的使用方法;这篇介绍Volley使用中更常用到的一些知识点;
建议先看上篇文章:Android Volley的使用(一)

文章结构如下:

这里写图片描述

使用请求队列RequestQueue

Volley中的Request都需要添加到RequestQueue中才能执行,所以首先需要创建一个RequestQueue

RequestQueue reqQueue=Volley.newRequestQueue(this);//this指的是Context对象

通常情况在一个应用中需要统一管理一个请求队列,所以采用单例模式(注意:这不是必须的,但是采用这种方式有很多好处~),即在整个应用中持有一个Application对象,通过创建一个继承自Application的类,并在这个类中初始化RequestQueue等核心对象,以及实现一些我们所需的方法;

public class ApplicationController extends Application{//创建一个TAG,方便调试或Log    private static final String  TAG=getApplication().getSimpleName();//创建一个全局的请求队列    private RequestQueue reqQueue;//创建一个static ApplicationController对象,便于全局访问    private static ApplicationController mInstance;    @Override    public void onCreate(){        super.onCreate();        //初始化        mInstance=this;    }    /**    *以下为需要我们自己封装的添加请求取消请求等方法    */    //用于返回一个ApplicationController单例    private static synchroized ApplicationController getInstance(){        return mInstance;    }    //用于返回全局RequestQueue对象,如果为空则创建它    public RequestQueue getRequestQueue(){        if(reqQueue==null)                         reqQueue=Volley.newRequestQueue(getApplicationContext);        return reqQueue;    }/***将Request对象添加进RequestQueue,由于Request有*StringRequest,JsonObjectResquest...等多种类型,所以需要用到*泛型。同时可将*tag作为可选参数以便标示出每一个不同请求*/    public <T> void addToRequestQueue(Request<T> req,String tag){    //如果tag为空的话,就是用默认TAG        req.setTag(TextUtils.isEmpty(tag)?TAG:tag);         getRequestQueue().add(req);    }    public <T> void addToRequestQueue(Request<T> req){        req.setTag(TAG);        getRequestQueue().add(req);    }//通过各Request对象的Tag属性取消请求    public void cancelPendingRequests(Object tag){        if(reqQueue!=null){            reqQueue.cancelAll(tag);        }    }}

Tips:实现自己的Application类后,我们需要在Manifest.xml中改写

<application android:name=".ApplicationController"        ....>

执行异步请求

上篇文章已经提到过,Volley主要提供了以下几种类型的异步请求:

  • JsonObjectRequest 用来接收和发送JsonObject类型的数据
  • JsonArrayRequest 用来接收和发送JsonArray类型的数据
  • StringRequest 用来接收和发送响应主体为String的数据

JsonObjectRequest

这是一个用来发送和接收JSON数据最常用的类,覆写这个类中的一些方法可以发送(GET,POST,DELETE,PUT)等适当的HTTP请求,常见操作代码示例:

final String url="http://www.jycoder.com/person.json";JsonObjectRequest req=new JsonObjectRequest(url,null,                            new Response.Listener<JsonObject>(){    @Override    public void onResponse(JsonObject response){    //正确响应时回调此函数    }},new ResponseError.Listener(){    @Override    public void onErrorResponse(VolleyError error){            //未正确响应时回调此函数    }});//将请求添加至全局RequestQueueApplicationController.getInstance().addToRequestQueue(req);

发送包含HTTP 请求方法(Post Put Get Delete)的 Request

如果我们想要发送Post,Delete等请求,可通过一个带请求参数的JsonObject对象来实现

//用来保存post参数HashMap<String,String> params=new HashMap<String,String>();params.put("userId","123189283");//new JsonObject(params) 作为 JsonObjectRequest 参数JsonObjectRequest req=new JsonObjectRequest(url,                        new JsonObject(params),                    new Response.Listener<JsonObject>(){...},                    new Response.ErrorListener(){...});

发送JsonArrayRequest StringRequestJsonObjectRequest类似

JsonArrayRequest req=new JsonArrayRequest(url,        new Response.Listener<JsonArray>(){..},        new Response.ErrorListener(){..});StringRequest req=new StringRequest(url,        new Response.Listener<String>(){..},        new Response.ErrorListener(){..});

取消Request

Volley框架提供了强大的API来支持取消正在等待或者运行的一个或多个请求,还记得我们先前提到的setTag()方法吗,正是通过Tag来标示每个Request,我们特可以通过这个Tag来取消Request

//可以通过setTag方法为每一个Request添加tagreq.setTag("My Tag");//也可以在我们实现的添加进RequestQueue的时候设置ApplicationController.getInstance().addToRequestQueue(req,"My Tag");//取消RequestreqQueue.cancelAll("My Tag");//或者我们前面实现的方法ApplicationController.getInstance().cancelPendingRequests("My Tag");

Tips:学习完上面三个方面的知识,我们就已经差不多掌握了Volley最常用的方法,如果想让你的应用更健壮,还需要了解Volley中的错误处理,设置请求失败重试机制和超时机制,设置请求优先级,设置请求头部等等

拓展部分

请求失败时的重试和请求自定义超时

Volley中提供了一个方案:可以通过Request对象调用setRetryPolicy()方法,设置超时和重试请求

request.setRetryPolicy(new DefaultRetryPolicy(20*1000,1,1.0f));/**DefaultRetryPolicy(int,int,float);中第一个代表超时时间:即超过20S认为超时,第三个参数代表最大重试次数,这里设置为1.0f代表如果超时,则不重试*/

设置请求优先级

在实际开发中我们常常需要提高一些请求的优先级以便优先执行,可以通过覆写getPrioriity()方法,

//优先级有LOW,NORMAL,HIGH,IMMEDIATEprivate Priority priority = Priority.HIGH;StringRequest strReq = new StringRequest(Method.GET,          Const.URL_STRING_REQ,           new Response.Listener<String>() {     @Override     public void onResponse(String response) {             Log.d(TAG, response.toString());             msgResponse.setText(response.toString());             hideProgressDialog();         }     }, new Response.ErrorListener() {      @Override      public void onErrorResponse(VolleyError error) {              VolleyLog.d(TAG, "Error: " + error.getMessage());              hideProgressDialog();      }  }) {     @Override      public Priority getPriority() {           return priority;      }};

设置请求头部(HTTP 头部)

很多时候需要给HTTP Request添加头部,一个典型的场景就是基本的HTTP 授权认证,Request类中提供了getHeaders()方法,你需要覆写并添加自己的自定义头部

@Overridepublic Map<String, String> getHeaders() throws AuthFailureError {    HashMap<String, String> headers = new HashMap<String, String>();    headers.put("CUSTOM_HEADER", "Yahoo");    headers.put("ANOTHER_CUSTOM_HEADER", "Google");    return headers;}

错误处理

你可能已经注意到了在创建Request对象时,构造参数中有new Response.ErrorListener(),这就是典型的错误处理

volley中错误主要有以下几类:

  • AuthFailureError — 基本的Http身份认证(授权)错误.
  • NetworkError — 网络错误
  • NoConnectionError — 网络连接错误.
  • ParseError — 数据解析错误.
  • ServerError — 服务端错误.
  • TimeoutError — 超时错误.

你可以实现自己的错误处理类,用来返回具体的错误信息

 public class VolleyErrorHelper {     //用于返回具体错误信息,分辨错误类别      public static String getMessage(Object error, Context context) {        if (error instanceof TimeoutError) {            return context.getResources().getString(R.string.generic_server_down);            }else if (isServerProblem(error)) {                return handleServerError(error, context);            }else if (isNetworkProblem(error)) {                return context.getResources().getString(R.string.no_internet);            }            return context.getResources().getString(R.string.generic_error);        }        //判断是否是网络错误        private static boolean isNetworkProblem(Object error) {            return (error instanceof NetworkError) ||                 (error instanceof NoConnectionError);        }        //判断是否是服务端错误        private static boolean isServerProblem(Object error) {            return (error instanceof ServerError) ||                 (error instanceof AuthFailureError);        }        //处理服务端错误        private static String handleServerError(Object err, Context context) {            VolleyError error = (VolleyError) err;            NetworkResponse response = error.networkResponse;            if (response != null) {                switch (response.statusCode) {                    case 404:                    case 422:                    case 401:                        try {                        // server might return error like this { "error": "Some error occured" }                        // Use "Gson" to parse the result                        HashMap<String, String> result = new Gson().fromJson(new String(response.data),                        new TypeToken<Map<String, String>>() {}.getType());            if (result != null && result.containsKey("error")) {                return result.get("error");            }            } catch (Exception e) {                e.printStackTrace();            }            return error.getMessage();            default:                return context.getResources().getString(R.string.generic_server_down);            }        }        return context.getResources().getString(R.string.generic_error);      }    }

总结:

综上,我们已经基本上学完了Volley框架的大部分知识,唯一还没有涉及到且比较重要的就是图像缓存方面的内容,将在下篇博客中介绍;记得关注个人微博,微信公众平台哦,

参考资料:Asynchronous HTTP Requests in Android Using Volley


  • 微博: @明桑Android黑历史
  • 邮箱: <13141459344@163.com>
  • 个人主页: 明桑战胜Android汪的黑历史

    ITBird

3 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 幼儿上课一半要离开怎么办 八个月宝宝消化不良拉肚子怎么办 8个月的宝宝拉肚子怎么办 孕8个月拉稀怎么办 孩子调皮好动爱说话怎么办 宝宝8个月不会爬怎么办 怀孕8个月不想要了怎么办 8个月宝宝发烧怎么办 八个月的小孩发烧怎么办 孩子8个月发烧38怎么办 8个宝宝发烧38度怎么办 怀孕八个月不想要怎么办 怀孕八个月不想要了怎么办 八个月宝宝拉肚子拉水怎么办 八个月的宝宝拉肚子怎么办 八个月发烧38度怎么办 孩子特别调皮好动该怎么办 孩子有好动症该怎么办 在幼儿园好动的孩子该怎么办 18个月宝宝上火怎么办 打孩子越打上瘾怎么办 八个月不想要了怎么办 胎儿心脏畸形肺动脉瓣闭锁怎么办 小孩爱动怎么办补什么 初中孩子下午上课总犯困怎么办 孩子上课精神不集中怎么办 孩子玩兴奋了就打人怎么办 婴儿兴奋白天不睡觉怎么办 小孩读书精神不集中怎么办 小孩上课精神不集中怎么办 小孩学习精神不集中怎么办 孩子暑假天天看电视不出门怎么办 七个月宝宝缺铁怎么办 天天运动为什么还便秘怎么办 小孩学习注意力不集中怎么办 8个月宝贝太好动怎么办 学生在校受伤家长该怎么办 多动症小孩爱动手指怎么办 孩子大了不听话该怎么办 流产后吹了风怎么办 怀孕1周内喝酒了怎么办