上一篇文章翻译了一下google的Volley官方文档,讲到了最基本的发送request。这一次我们来下一回:创建一个自定义RequestQueue。
这篇文章将会教你一步一步创建自己的RequestQueue,并定制你自己的行为。
第一步:使用定制的Network和cache
一个RequestQueue需要两样东西去完成他的工作:即发送请求的network和处理缓存的cache。在Volley中有两个实现的标准接口:那么DiskBasedCache提供一个
一个response对应一个文件的缓存和内存级别的索引。BasicNetwork提供基于Http client的网络传输。
BasicNetwork是Volley默认网络的网络接口,它必须被一个你正在使用的Http client初始化才能使用。就像下面这样:
1 RequestQueue mRequestQueue; 2 3 // Instantiate the cache 4 Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap 5 6 // Set up the network to use HttpURLConnection as the HTTP client. 7 Network network = new BasicNetwork(new HurlStack()); 8 9 // Instantiate the RequestQueue with the cache and network. 10 mRequestQueue = new RequestQueue(cache, network); 11 12 // Start the queue 13 mRequestQueue.start(); 14 15 String url ="http://www.example.com"; 16 17 // Formulate the request and handle the response. 18 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 19 new Response.Listener<String>() { 20 @Override 21 public void onResponse(String response) { 22 // Do something with the response 23 } 24 }, 25 new Response.ErrorListener() { 26 @Override 27 public void onErrorResponse(VolleyError error) { 28 // Handle error 29 } 30 }); 31 32 // Add the request to the RequestQueue. 33 mRequestQueue.add(stringRequest);
如果你只是一次性请求并且想要使用线程池,你可以在任意你想要的时候创建RequestQueue,然后再数据返回或者出错后调用stop()方法。但是更常用的方式是以单例的
方式去创建RequestQueue保证它运行在你的应用的生命周期内。
第二步:使用单例模式
如果你的应用持续使用网络,那么最好使用单例模式。实现它有很多种方式,推荐使用实现一个封装好RequestQueue和Volley其他功能的类。另一种方法是继承Application
并且在你的Application.onCreate()方法中创建RequestQueue
,但是这种方法是不被推荐的。一个单例可以实现同样的功能并且更加符合模块化的设计。
重要的一点是RequestQueue必须使用Application context而不是一个Activity Context。这可以保证RequestQueue在app的整个生命周期内都有效,而不是每次重新创建
Activity都要重新创建(比如手机从横屏到竖屏)。
下面是一个栗子:
1 public class MySingleton { 2 private static MySingleton mInstance; 3 private RequestQueue mRequestQueue; 4 private ImageLoader mImageLoader; 5 private static Context mCtx; 6 7 private MySingleton(Context context) { 8 mCtx = context; 9 mRequestQueue = getRequestQueue(); 10 11 mImageLoader = new ImageLoader(mRequestQueue, 12 new ImageLoader.ImageCache() { 13 private final LruCache<String, Bitmap> 14 cache = new LruCache<String, Bitmap>(20); 15 16 @Override 17 public Bitmap getBitmap(String url) { 18 return cache.get(url); 19 } 20 21 @Override 22 public void putBitmap(String url, Bitmap bitmap) { 23 cache.put(url, bitmap); 24 } 25 }); 26 } 27 28 public static synchronized MySingleton getInstance(Context context) { 29 if (mInstance == null) { 30 mInstance = new MySingleton(context); 31 } 32 return mInstance; 33 } 34 35 public RequestQueue getRequestQueue() { 36 if (mRequestQueue == null) { 37 // getApplicationContext() is key, it keeps you from leaking the 38 // Activity or BroadcastReceiver if someone passes one in. 39 mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); 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 } 51 }
1 // Get a RequestQueue 2 RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()). 3 getRequestQueue(); 4 5 // ... 6 7 // Add a request (in this example, called stringRequest) to your RequestQueue. 8 MySingleton.getInstance(this).addToRequestQueue(stringRequest);