205 lines
7.3 KiB
Plaintext
205 lines
7.3 KiB
Plaintext
page.title=Setting Up a RequestQueue
|
|
|
|
trainingnavtop=true
|
|
|
|
@jd:body
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<!-- table of contents -->
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li><a href="#network">Set Up a Network and Cache</a></li>
|
|
<li><a href="#singleton">Use a Singleton Pattern</a></li>
|
|
</ol>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
|
|
<div>
|
|
<h3>Video</h3>
|
|
<p>Volley: Easy, Fast Networking for Android</p>
|
|
</div>
|
|
</a>
|
|
|
|
|
|
<p>The previous lesson showed you how to use the convenience method
|
|
<code>Volley.newRequestQueue</code> to set up a {@code RequestQueue}, taking advantage of
|
|
Volley's default behaviors. This lesson walks you through the explicit steps of creating a
|
|
{@code RequestQueue}, to allow you to supply your own custom behavior.</p>
|
|
|
|
<p>This lesson also describes the recommended practice of creating a {@code RequestQueue}
|
|
as a singleton, which makes the {@code RequestQueue} last the lifetime of your app.</p>
|
|
|
|
<h2 id="network">Set Up a Network and Cache</h2>
|
|
|
|
<p>A {@code RequestQueue} needs two things to do its job: a network to perform transport
|
|
of the requests, and a cache to handle caching. There are standard implementations of these
|
|
available in the Volley toolbox: {@code DiskBasedCache} provides a one-file-per-response
|
|
cache with an in-memory index, and {@code BasicNetwork} provides a network transport based
|
|
on your choice of {@link android.net.http.AndroidHttpClient} or {@link java.net.HttpURLConnection}.</p>
|
|
|
|
<p>{@code BasicNetwork} is Volley's default network implementation. A {@code BasicNetwork}
|
|
must be initialized with the HTTP client your app is using to connect to the network.
|
|
Typically this is {@link android.net.http.AndroidHttpClient} or
|
|
{@link java.net.HttpURLConnection}:</p>
|
|
<ul>
|
|
<li>Use {@link android.net.http.AndroidHttpClient} for apps targeting Android API levels
|
|
lower than API Level 9 (Gingerbread). Prior to Gingerbread, {@link java.net.HttpURLConnection}
|
|
was unreliable. For more discussion of this topic, see
|
|
<a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">
|
|
Android's HTTP Clients</a>. </li>
|
|
|
|
<li>Use {@link java.net.HttpURLConnection} for apps targeting Android API Level 9
|
|
(Gingerbread) and higher.</li>
|
|
</ul>
|
|
<p>To create an app that runs on all versions of Android, you can check the version of
|
|
Android the device is running and choose the appropriate HTTP client, for example:</p>
|
|
|
|
<pre>
|
|
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);
|
|
</pre>
|
|
|
|
<p>This snippet shows you the steps involved in setting up a
|
|
{@code RequestQueue}:</p>
|
|
|
|
<pre>
|
|
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);
|
|
...
|
|
</pre>
|
|
|
|
<p>If you just need to make a one-time request and don't want to leave the thread pool
|
|
around, you can create the {@code RequestQueue} wherever you need it and call {@code stop()} on the
|
|
{@code RequestQueue} once your response or error has come back, using the
|
|
{@code Volley.newRequestQueue()} method described in <a href="simple.html">Sending a Simple
|
|
Request</a>. But the more common use case is to create the {@code RequestQueue} as a
|
|
singleton to keep it running for the lifetime of your app, as described in the next section.</p>
|
|
|
|
|
|
<h2 id="singleton">Use a Singleton Pattern</h2>
|
|
|
|
<p>If your application makes constant use of the network, it's probably most efficient to
|
|
set up a single instance of {@code RequestQueue} that will last the lifetime of your app.
|
|
You can achieve this in various ways. The recommended approach is to implement a singleton
|
|
class that encapsulates {@code RequestQueue} and other Volley
|
|
functionality. Another approach is to subclass {@link android.app.Application} and set up the
|
|
{@code RequestQueue} in {@link android.app.Application#onCreate Application.onCreate()}.
|
|
But this approach is <a href="{@docRoot}reference/android/app/Application.html">
|
|
discouraged</a>; a static singleton can provide the same functionality in a more modular
|
|
way. </p>
|
|
|
|
<p>A key concept is that the {@code RequestQueue} must be instantiated with the
|
|
{@link android.app.Application} context, not an {@link android.app.Activity} context. This
|
|
ensures that the {@code RequestQueue} will last for the lifetime of your app, instead of
|
|
being recreated every time the activity is recreated (for example, when the user
|
|
rotates the device).
|
|
|
|
<p>Here is an example of a singleton class that provides {@code RequestQueue} and
|
|
{@code ImageLoader} functionality:</p>
|
|
|
|
<pre>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;
|
|
}
|
|
}</pre>
|
|
|
|
<p>Here are some examples of performing {@code RequestQueue} operations using the singleton
|
|
class:</p>
|
|
|
|
<pre>
|
|
// 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);
|
|
</pre>
|