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.AuthFailureError; 8 import com.android.volley.NetworkResponse; 9 import com.android.volley.ParseError; 10 import com.android.volley.Request; 11 import com.android.volley.Response; 12 import com.android.volley.Response.ErrorListener; 13 import com.android.volley.Response.Listener; 14 import com.android.volley.toolbox.HttpHeaderParser; 15 import com.google.gson.Gson; 16 import com.google.gson.JsonSyntaxException; 17 18 public class JsonRequestWithAuth<T> extends Request<T> 19 { 20 private final Gson gson = new Gson(); 21 private final Class<T> clazz; 22 private final Listener<T> listener; 23 24 private static Map<String, String> mHeader = new HashMap<String, String>(); 25 /** 26 * 设置访问自己服务器时必须传递的参数,密钥等 27 */ 28 static 29 { 30 mHeader.put("APP-Key", "LBS-AAA"); 31 mHeader.put("APP-Secret", "ad12msa234das232in"); 32 } 33 34 /** 35 * @param url 36 * @param clazz 37 * 我们最终的转化类型 38 * @param headers 39 * 请求附带的头信息 40 * @param listener 41 * @param appendHeader 42 * 附加头数据 43 * @param errorListener 44 */ 45 public JsonRequestWithAuth(String url, Class<T> clazz, Listener<T> listener, Map<String, String> appendHeader, 46 ErrorListener errorListener) 47 { 48 super(Method.GET, url, errorListener); 49 this.clazz = clazz; 50 this.listener = listener; 51 mHeader.putAll(appendHeader); 52 } 53 54 @Override 55 public Map<String, String> getHeaders() throws AuthFailureError 56 { 57 // 默认返回 return Collections.emptyMap(); 58 return mHeader; 59 } 60 61 @Override 62 protected void deliverResponse(T response) 63 { 64 listener.onResponse(response); 65 } 66 67 @Override 68 protected Response<T> parseNetworkResponse(NetworkResponse response) 69 { 70 try 71 { 72 /** 73 * 得到返回的数据 74 */ 75 String jsonStr = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 76 /** 77 * 转化成对象 78 */ 79 return Response.success(gson.fromJson(jsonStr, clazz), HttpHeaderParser.parseCacheHeaders(response)); 80 } catch (UnsupportedEncodingException e) 81 { 82 return Response.error(new ParseError(e)); 83 } catch (JsonSyntaxException e) 84 { 85 return Response.error(new ParseError(e)); 86 } 87 } 88 }
这里说一下,我在Header中放置了APP-key等数据,也就是说只要我们这个请求发的都会有这几个值,大家开发app时肯定有很多请求参数是需要每次都发往服务器校验的,可以在这里设置。
二 使用单例模式(封装RequestQueue )
如果app连接网络比较频繁,最合理的方式就是把RequestQueue实现为单实例类型,并这个实例在app运行的整个生命周期中存活。有两种方式实现 单实例,推荐的一种做法就是实现一个封装了请求队列和其他volley功能的单例类。还有一种不建议使用的方式就是创建一个继承Application的 字类,并在Application.onCreate()方法中创建请求队列。一个静态的单实例类能够以模块化的方式提供同样的功能。
使 用推荐的方式实现单实例最重要的概念就是请求队列对象必须以应用上下文(application context)而不是活动上下文(activity context)的形式进行实例化。以此确保了请求队列对象在app运行的整个生命周期中存在,而不是随着活动的重新创建而创建。结合设计模式单例模式的 实现,来看看MySingleton.java类的实现,这个类提供了一个请求队列和图片加载:
1 private static MySingleton mInstance; 2 private RequestQueue mRequestQueue; 3 private ImageLoader mImageLoader; 4 private static Context mCtx; 5 6 private MySingleton(Context context){ 7 mCtx = context; 8 mRequestQueue = getRequestQueue(); 9 10 mImageLoader = new ImageLoader(mRequestQueue,n 11 new ImageLoader.ImageCache(){ 12 private final LruCache<String,Bitmap>(20) 13 cache = new LruCache<String,Bitmap>(20); 14 15 @Override 16 public Bitmap getBitmap(String url){ 17 return cache.get(url); 18 } 19 @Override 20 public void putBitmap(String url,Bitmap bitmap){ 21 cache.put(url,bitmap); 22 } 23 }); 24 } 25 26 //异步获取单实例 27 public static synchronized MySingleton getInstance(Context context){ 28 if(mInstance == null){ 29 mInstance = new MySingleton(context); 30 } 31 return mInstance 32 } 33 34 public RequestQueue getRuquestQueue(){ 35 if(mRequestQueue == null){ 36 //getApplication()方法返回一个当前进程的全局应用上下文,这就意味着 37 //它的使用情景为:你需要一个生命周期独立于当前上下文的全局上下文, 38 //即就是它的存活时间绑定在进程中而不是当前某个组建。 39 mRequestQueue = Volley.newRequestQueue(mCtx.getApplication()); 40 } 41 return mRequestQueue; 42 } 43 44 public <T> void addToRequestQueue(Request<T>req){ 45 getRequestQueue.add(req); 46 } 47 48 public ImageLoader getImageLoader(){ 49 return mImageLoader; 50 }
在上面的代码中,构造方法中封装了请求队列和图片加载,接着就是异步获取实例、获取请求队列、把请求添加到请求队列、获取图片加载。
最后我们使用这个单例类执行请求队列操作:
1 //获取请求队列 2 RequestQueue queue = MySingleton.getInstance(this.getApplication(). 3 getRequest(); 4 ....... 5 //把请求(在这个例子中请求为StringRequest)添加到请求队列 6 MySingleton.getInstance(this).addToRequestQueue(StringRequest);
参考自:
http://my.oschina.net/huangwenwei/blog/287611
http://blog.csdn.net/lmj623565791/article/details/24589837