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,希望和大家能共同的进步~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值