zoukankan      html  css  js  c++  java
  • Android Volley框架的使用(二)

    在上一篇文章中介绍了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){
                //未正确响应时回调此函数
        }
    });
    
    //将请求加入至全局RequestQueue
    ApplicationController.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加入tag
    req.setTag("My Tag");
    //也能够在我们实现的加入进RequestQueue的时候设置
    ApplicationController.getInstance().addToRequestQueue(req,"My Tag");
    
    //取消Request
    reqQueue.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,IMMEDIATE
    private 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()方法。你须要覆写并加入自己的自己定义头部

    @Override
    public 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


  • 相关阅读:
    静态内存不能跨函数使用
    多级指针
    数组大小的动态分配
    luoguP1629 邮递员送信
    luoguP1119 灾后重建
    luoguP1395 会议
    树的重心
    luoguP5536 【XR-3】核心城市
    树的直径
    luoguP5836 [USACO19DEC]Milk Visits S
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7228280.html
Copyright © 2011-2022 走看看