上篇文章简单的介绍了volley的使用,这篇偶将继续和大家一起分享volley的使用。
其实忘记一件很重要的事情,我相信也是很多初识volley的人困惑的地方,就是从哪里开始学习,认识volley,使用volley,可能你谷歌或者百度到的最多的就是一个简单demo或者对volley介绍的翻译,如果你很牛可能理解起来很容易,但是对于我等菜鸟还是有点难度的。虽然偶的水平有限,但是我会尽量遵照自己这段时间对volley的认识过程来总结。
上篇提到我们不会直接在Activiy中创建volley的请求队列对象,因为这个对象我们只要一个就够了。既然不这样那我们该怎么做呢,这里给一个建议。先上一张项目结构图:
思路是这样的:我们在application中对volley进行初始化。然后通过静态方法拿到这个对象,即可在所有地方使用,关键代码如下(来自:https://github.com/ogrebgr):
/** * 这段代码来自这里:https://github.com/ogrebgr * * @author ttdevs */ public class VolleyQueue { private static RequestQueue mRequestQueue; private static ImageLoader mImageLoader; private VolleyQueue() { } /** * 初始化我们的请求队列。这个地方有一个BitmapLruCache,这个是在后面做图片加载的时候会提到的图片缓存策略 * * @param context */ static void init(Context context) { mRequestQueue = Volley.newRequestQueue(context); int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); // Use 1/8th of the available memory for this memory cache. int cacheSize = 1024 * 1024 * memClass / 8; mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(cacheSize)); } public static RequestQueue getRequestQueue() { if (mRequestQueue != null) { return mRequestQueue; } else { throw new IllegalStateException("RequestQueue not initialized"); } } public static ImageLoader getImageLoader() { if (mImageLoader != null) { return mImageLoader; } else { throw new IllegalStateException("ImageLoader not initialized"); } } }这样我们就可以在想要的地方随意使用了。
public class CustomReqeust extends Request<String> { private final Listener<String> mListener; public CustomReqeust(int method, String url, Listener<String> listener, ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { // TODO Auto-generated method stub return null; } @Override protected void deliverResponse(String response) { // TODO Auto-generated method stub } }我们简单的分析下这几行代码。首先是构造函数,通过super我们发现,构造函数中我们需要提供三个参数,分别是:method、url、errorListener,它们的意思分别是:请求方式,即POST/GET;请求的URL;出错时的回调监听器。而StringRequest的构造函数中多了一个Listener<String> listener,这个通过前面的demo大家应该知道它是用来处理请求结果的,当然大部分情况我们是需要这个东西的,因此我们把它加上。这样就完整了。下面还有两个必须实现的方法,这个是干什么的呢?我们先来看看StringRequest中这两个方法的实现:
@Override protected void deliverResponse(String response) { mListener.onResponse(response); } @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)); }
protected void deliverResponse(String response) {}传递响应,通过我们初始化时候设置的成功监听器来传递HTTP响应结果。
protected Response<String> parseNetworkResponse(NetworkResponse response){}
/** * Returns the raw POST or PUT body to be sent. * * @throws AuthFailureError in the event of auth failure */ @Override public byte[] getBody() { try { return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET); } catch (UnsupportedEncodingException uee) { VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, PROTOCOL_CHARSET); return null; } }对,你猜的没错,他就是处理我们请求参数的方法,在这里我们组织好要传的参数,然后转换成byte数组即可。这样我们就可以开始实现自己自定义的请求了。下面贴一个简单的完整例子供参考:
public class CustomReqeust extends Request<String> { /** http请求编码方式 */ private static final String PROTOCOL_CHARSET = "utf-8"; private Listener<String> mListener; private String mUserName; public CustomReqeust(String url, String userName, Listener<String> listener, ErrorListener errorListener) { super(Method.POST, url, errorListener); mUserName = userName; mListener = listener; } @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)); } @Override protected void deliverResponse(String response) { mListener.onResponse(response); } @Override public byte[] getBody() { try { return mUserName == null ? null : mUserName.getBytes(PROTOCOL_CHARSET); } catch (UnsupportedEncodingException uee) { VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mUserName, PROTOCOL_CHARSET); return null; } } }调用代码不想不贴,但是要用到,还是贴一下(这里的URL还是www.baidu.com):
private void customRequest() { CustomReqeust request = new CustomReqeust(URL, "CustomVolley", new Listener<String>() { @Override public void onResponse(String arg0) { Toast.makeText(getApplicationContext(), arg0, Toast.LENGTH_LONG).show(); Log.d("onResponse", arg0); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError arg0) { Toast.makeText(getApplicationContext(), arg0.toString(), Toast.LENGTH_LONG).show(); Log.d("onErrorResponse", arg0.toString()); } }); mQueue.add(request); }由于没有测试服务器,因此就简单的抓包看一下,结果如下: