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 the Apache HTTP client {@code 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 a {@link java.net.HttpURLConnection}:</p>
<ul>
<li>Use {@code 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&lt;String&gt;() {
    &#64;Override
    public void onResponse(String response) {
        // Do something with the response
    }
},
    new Response.ErrorListener() {
        &#64;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>public class MySingleton {
    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&lt;String, Bitmap&gt;
                    cache = new LruCache&lt;String, Bitmap&gt;(20);

            &#64;Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            &#64;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 &lt;T&gt; void addToRequestQueue(Request&lt;T&gt; 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>
