前一节向你说明了如何使用convenience方法Volley.newRequestQueue来建立一个RequestQueue,以利用Volley的默认行为。这一节将带你了解创建一个RequestQueue的显式步骤,以允许你提供你自己的定制行为。
这一节也会描述推荐的实践,即将一个RequestQueue创建为一个单例,这将会使RequestQueue在你的app的整个生命周期中持续。
建立一个Network和Cache
一个RequestQueue需要两个东西来执行它的工作:一个network来执行requests的传输,及一个cache来处理caching。在Volley的toolbox中有这些东西的标准实现可用:DiskBasedCache提供了一个具有一个in-memory 索引的one-file-per-response cache,BasicNetwork提供了一个基于你所选择的AndroidHttpClient或HttpURLConnection的网络传输。
BasicNetwork是Volley的默认网络实现。一个BasicNetwork必须用你的app借以连接网络的HTTP客户端初始化。典型地是AndroidHttpClient或HttpURLConnection:
- 对于那些目标平台的Android API levels低于API Level 9 (Gingerbread) 的app使用AndroidHttpClient。在Gingerbread之前,HttpURLConnection是不可靠的。关于这个主题的更多讨论,可以参考Android's HTTP Clients。
- 对于那些目标平台为Android API Level 9 (Gingerbread) 或更高的app使用HttpURLConnection。
要创建一个在所有的Android版本上运行的app,你可以检查设备运行的Android版本并选择适当的HTTP客户端,比如:
HttpStack stack;
...
// If the device is running a version >= Gingerbread...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
// ...use HttpURLConnection for stack.
} else {
// ...use AndroidHttpClient for stack.
}
Network network = new BasicNetwork(stack);
这个代码片段向你展示了建立一个RequestQueue的步骤:
RequestQueue mRequestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);
// Start the queue
mRequestQueue.start();
String url ="http://www.myurl.com";
// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Do something with the response
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle error
}
});
// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
...
如果你只需要一个one-time request,并且不希望有一个线程池在那里,你可以在你需要的地方创建RequestQueue,并在你的response或error返回之后立即调用RequestQueue的stop()方法,使用在发送一个简单的请求一节中描述的Volley.newRequestQueue()方法。但是更常见的用法是,如在下一节中描述的那样,把RequestQueue创建为一个单例,并使它在你的app的整个生命周期一直运行。
使用一个单例模式
如果你的应用程序持续使用网络,可能地最高效的方式是建立一个将在你的app的整个生命周期中持续运行的单实例的RequestQueue。你可以以多种方法做到这一点。建议的方法是实现一个单例类来封装RequestQueue及其他的Volley功能。另一个方法是继承Application,并在Application.onCreate()中建立RequestQueue。但是这种方法是不鼓励的;一个静态的单例可以以一种更加模块化的方式提供相同的功能。
一个重要的概念是,RequestQueue必须以Application context来初始化,而不是Activity context。这样可以确保RequestQueue将在你的app的生命周期中持续运行,而不是在activity每次重建时(比如,当用户旋转设备时)都重建。
这里是一个单例类的例子,它提供了RequestQueue和ImageLoader功能:
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
这里是一些使用单例类执行RequestQueue 操作的例子:
// Get a RequestQueue
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
getRequestQueue();
...
// Add a request (in this example, called stringRequest) to your RequestQueue.
MySingleton.getInstance(this).addToRequestQueue(stringRequest);
译自:http://developer.android.com/training/volley/requestqueue.html
Done.