Volley使用技巧-----自定义Request

Volley使用技巧—–自定义Request

题外话

最近在和网络请求较劲,也初步接触了下volley,看了各路大神的各种理论分析,现在把自己使用volley的一点小经验拿出来和大家分享,特别是在cookie这个小问题上,由于人笨了,纠结了一段时间.

Volley简介

Google I/O 2013上,Volley发布了。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。这是Volley名称的由来: a burst or emission of many things or a large amount at once

适合数据量小的,通信频繁的各种请求,官方已经封装好了各种API,而且还提供了很灵活的自定义请求接口,不仅使用起来方便,可扩展性也很强.

获取Volley的方法有很多,这里直接给出jar的包,方便下载

功能介绍

  • JSON,图像等的异步下载;
  • 网络请求的排序(scheduling)
  • 网络请求的优先级处理
  • 缓存
  • 多级别取消请求和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)

实战演习

由于API都已经封装好了,使用起来也是非常的简单,只需要如下三个步骤:

//新建网络请求的队列
mQueue = Volley.newRequestQueue(getApplicationContext());
//向队列中加入创建好的请求
mQueue.add(new JsonObjectRequest(Method.GET, url, null,
            new Listener() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, "response : " + response.toString());
                }
            }, null));
//启动队列,开始执行请求
mQueue.start();

下面用一个小例子来看看Volley的最简单用法:

首先在AndroidManifest.xml中加入如下的权限,否则不能进行网络访问:

<uses-permission android:name="android.permission.INTERNET" />  

接下来就是主要的代码部分:

public class MainActivity extends ActionBarActivity {
  //提交请求的按钮
  private Button request;
  //volley的请求队列
  private RequestQueue requestQueue;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    request = (Button) findViewById(R.id.request);
    //初始化请求队列
    requestQueue = Volley.newRequestQueue(getApplicationContext());
    request.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        //处理请求成功返回的结果
        Response.Listener<String> listener = new Response.Listener<String>() {
          @Override
          public void onResponse(String s) {
            Log.e("dada", s);
          }
        };
        //处理请求错误返回的结果
        Response.ErrorListener errorListener = new Response.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError volleyError) {
            Log.e("error", volleyError.toString());
          }
        };
        //实例化请求对象
        StringRequest stringRequest = new StringRequest("http://www.baidu.com", listener, errorListener);
        //向队列中加入请求
        requestQueue.add(stringRequest);
        requestQueue.start();
      }
    });
  }
}

上面的属于直接用官方封装好了的request,但是如果官方的request不符合自己的条件,比如说下面这个JSONArrayRequest的代码就是官方给出的:

/**
 * A request for retrieving a {@link JSONArray} response body at a given URL.
 */
public class JsonArrayRequest extends JsonRequest<JSONArray> {
    /**
     * Creates a new request.
     * @param url URL to fetch the JSON from
     * @param listener Listener to receive the JSON response
     * @param errorListener Error listener, or null to ignore errors.
     */
    public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
        super(Method.GET, url, null, listener, errorListener);
    }

//这个函数是在请求执行完成后,对返回的结果NetworkResponse进行处理,实际上这个结果是Volley已经处理过一次,这里再将这个结果转化为想要的格式类型,在后面的StringRequest中也可以看到相同格式的结果,这对我们自定义request很有帮助
    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString =
                new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONArray(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }
}

不难发现上面的JSONArrayRequest只允许进行get请求,而无法进行post请求,于是需要自己去定义.再看看官方给出的StringRequest.java源代码:

/**
 * A canned request for retrieving the response body at a given URL as a String.
 */
public class StringRequest extends Request<String> {
    private final Listener<String> mListener;

    /**
     * Creates a new request with the given method.
     *
     * @param method the request {@link Method} to use
     * @param url URL to fetch the string at
     * @param listener Listener to receive the String response
     * @param errorListener Error listener, or null to ignore errors
     */
    public StringRequest(int method, String url, Listener<String> listener,
            ErrorListener errorListener) {
        super(method, url, errorListener);
        mListener = listener;
    }

    /**
     * Creates a new GET request.
     *
     * @param url URL to fetch the string at
     * @param listener Listener to receive the String response
     * @param errorListener Error listener, or null to ignore errors
     */
    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
        this(Method.GET, url, listener, errorListener);
    }

    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }
//这个地方和上面的JSONArrayRequest请求的返回结果都相同,都是NetworkResponse,我们在自定义的时候也可以模仿这这些处理进行操作.
    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }
}

在看完了上面的两个请求代码之后,我们能够总结出如下几个相同点,以便我们自定义使用:

  1. 从Request类继承
  2. 相应的构造方法,参数可以参照上面的几种,自选
  3. 处理返回结果paraseNetworkResponse(NetworkResponse response)

    下面是自定义的请求代码:

public class JsonArrayRequestPlus extends Request<JSONArray>{

  //请求完成之后的回调方法,用来传递请求结果
  private final Response.Listener<JSONArray> mListener;

  /**
   * 构造方法
   * @param method(请求方法)
   * @param url(请求的url)
   * @param listener(请求成功后处理结果的监听器)
   * @param errorListener(请求错误后的监听器)
   */
  public JsonArrayRequestPlus(int method,
                              String url,
                              Response.Listener<JSONArray> listener,
                              Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    mListener = listener;
  }
  @Override
  public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    if(headers == null || headers.equals(Collections.emptyMap())){
      headers = new HashMap<>();
    }
    RequestQueueController.get().addSessionCookie(headers);
    return headers;
  }
  //将结果传递到构造方法中listener实例化的地方
  @Override
  protected void deliverResponse(JSONArray jsonArray) {
    mListener.onResponse(jsonArray);
  }
  //对NetworkResponse进行处理,处理的方式直接copy的JSONArrayRequest
  @Override
  protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
    RequestQueueController.get().checkSessionCookie(response.headers);
    try {
      String jsonString =
              new String(response.data, HttpHeaderParser.parseCharset(response.headers));
      return Response.success(new JSONArray(jsonString),
              HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
      return Response.error(new ParseError(e));
    } catch (JSONException je) {
      return Response.error(new ParseError(je));
    }
  }
}

自定义的JSONArrayRequestPlus能保证返回的结果为JSONArray的同时,还能满足get和post请求,更多的自定义Request需要联系实际的情况来定.今天的自定义Request就到这里咯,有什么错误或者不懂得给我留言或者直接Q我2319821734,希望和大家能共同的进步~

时间: 2024-10-12 09:23:12

Volley使用技巧-----自定义Request的相关文章

Android Volley 之自定义Request

可以在Ext.QuickTips.init();后加入如下代码: Ext.MessageBox.buttonText = { ok : "确定", cancel : "取消", yes : "是", no : "否" }; Android Volley 之自定义Request,码迷,mamicode.com

Volley自定义Request及使用单例封装RequestQueue

一.自定义Request Volley的所有的请求的超类型是Resuest,所有我们常用的请求都是这个类的子类,那么我们自定义View肯定也是基于这个类的. 案例: 1 package com.zhy.velloydemo; 2 3 import java.io.UnsupportedEncodingException; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import com.android.volley.AuthFa

详细解读Volley(四)—— 自定义Request

Volley中提供了几个Request,如果我们有特殊的需求,完全可以自定义Request的,自定义Request自然要继承Request,那么本篇就教大家来一步一步地定义一个自己的Request类. 一.继承Request 如果我们的request的对象不是string,也不是JsonObject,而是一个奇怪的对象呢?我这里建立了一个类,叫做:Kale,然后定义了一个CustomReqeust去继承Reqeust,得到如下的代码. package com.kale.volleytest; i

Volley(五)—— 自定义Request

详细解读Volley(四)—— 自定义Request Volley中提供了几个Request,如果我们有特殊的需求,完全可以自定义Request的,自定义Request自然要继承Request,那么本篇就教大家来一步一步地定义一个自己的Request类. 一.继承Request 如果我们的request的对象不是string,也不是JsonObject,而是一个奇怪的对象呢?我这里建立了一个类,叫做:Kale,然后定义了一个CustomReqeust去继承Reqeust,得到如下的代码. pac

VC 绘图技巧--自定义形状图形

自定义形状图形,定义几个点围城的图形,然后进行描边和填充: [cpp] view plaincopy if (m_memDC.m_hDC!=NULL) { CPoint point[4]; point[0].x=nLeft+(int)(0.1*m_nWidth); point[0].y=m_nYmargin; point[1].x=nLeft+(int)(0.9*m_nWidth); point[1].y=m_nYmargin; point[2].x=nLeft+(int)(0.7*m_nWid

[Android] 开源框架 Volley 自定义 Request

今天在看Volley demo (https://github.com/smanikandan14/Volley-demo), 发现自定义GsonRequest那块代码不全, 在这里贴一个全的. public class GsonRequest<T> extends Request<T> { private Gson mGson; private Class mJavaClass; private Response.Listener<T> mListener; publ

Android.Volley的解读:request

这文章是用来记录自己最近使用volley的StringRequest的一些心得,以及volley关于request的代码深读. 从网络上可以知道,volley适合数据量不大但是通信频繁的场景.volley提供的便利功能有如下这些: JSON,图像等的异步下载: 网络请求的排序(scheduling) 网络请求的优先级处理 缓存 多级别取消请求 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 从一些网络前辈和自己使用的情况来说,volley的图片处理并不是最佳,我

requests库之自定义request

阅读requests源码会有更清楚的理解. tcp/ip的三次握手,使用requests每次请求会占用更多资源,使用session则可以重复使用一个request. 自定义requests:首先定义session(proxy,timeout,verify--),定义request(body,headers,author--)然后用prepare方法进行包装,最后用session使用send方法发出请求. 实例: import json import requests from requests

Android 使Volley完美支持自定义证书的Https

其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在2.3版本以上还是在2.3版本以下,大家可以尝试用volley去访问github 是成功的,但是你如果用volley去访问 12306这种类似的 用自定义证书的网站 就很容易失败.那我下面就把volley 代码稍作修改,让volley也可以完美支持自定义证书的https请求. 当然代码只是展示功能使