Home | History | Annotate | Download | only in volley
      1 page.title=Setting Up a RequestQueue
      2 
      3 trainingnavtop=true
      4 
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8 <div id="tb">
      9 
     10 <!-- table of contents -->
     11 <h2>This lesson teaches you to</h2>
     12 <ol>
     13   <li><a href="#network">Set Up a Network and Cache</a></li>
     14   <li><a href="#singleton">Use a Singleton Pattern</a></li>
     15 </ol>
     16 
     17 </div>
     18 </div>
     19 
     20 <a class="notice-developers-video wide" href="https://developers.google.com/events/io/sessions/325304728">
     21 <div>
     22     <h3>Video</h3>
     23     <p>Volley: Easy, Fast Networking for Android</p>
     24 </div>
     25 </a>
     26 
     27 
     28 <p>The previous lesson showed you how to use the convenience method
     29 <code>Volley.newRequestQueue</code> to set up a {@code RequestQueue}, taking advantage of
     30 Volley's default behaviors. This lesson walks you through the explicit steps of creating a
     31 {@code RequestQueue}, to allow you to supply your own custom behavior.</p>
     32 
     33 <p>This lesson also describes the recommended practice of creating a {@code RequestQueue}
     34 as a singleton, which makes the {@code RequestQueue} last the lifetime of your app.</p>
     35 
     36 <h2 id="network">Set Up a Network and Cache</h2>
     37 
     38 <p>A {@code RequestQueue} needs two things to do its job: a network to perform transport
     39 of the requests, and a cache to handle caching. There are standard implementations of these
     40 available in the Volley toolbox: {@code DiskBasedCache} provides a one-file-per-response
     41 cache with an in-memory index, and {@code BasicNetwork} provides a network transport based
     42 on your choice of {@link android.net.http.AndroidHttpClient} or {@link java.net.HttpURLConnection}.</p>
     43 
     44 <p>{@code BasicNetwork} is Volley's default network implementation. A {@code BasicNetwork}
     45 must be initialized with the HTTP client your app is using to connect to the network.
     46 Typically this is {@link android.net.http.AndroidHttpClient} or
     47 {@link java.net.HttpURLConnection}:</p>
     48 <ul>
     49 <li>Use {@link android.net.http.AndroidHttpClient} for apps targeting Android API levels
     50 lower than API Level 9 (Gingerbread). Prior to Gingerbread, {@link java.net.HttpURLConnection}
     51 was unreliable. For more discussion of this topic, see
     52 <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">
     53 Android's HTTP Clients</a>. </li>
     54 
     55 <li>Use {@link java.net.HttpURLConnection} for apps targeting Android API Level 9
     56 (Gingerbread) and higher.</li>
     57 </ul>
     58 <p>To create an app that runs on all versions of Android, you can check the version of
     59 Android the device is running and choose the appropriate HTTP client, for example:</p>
     60 
     61 <pre>
     62 HttpStack stack;
     63 ...
     64 // If the device is running a version >= Gingerbread...
     65 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
     66     // ...use HttpURLConnection for stack.
     67 } else {
     68     // ...use AndroidHttpClient for stack.
     69 }
     70 Network network = new BasicNetwork(stack);
     71 </pre>
     72 
     73 <p>This snippet shows you the steps involved in setting up a
     74 {@code RequestQueue}:</p>
     75 
     76 <pre>
     77 RequestQueue mRequestQueue;
     78 
     79 // Instantiate the cache
     80 Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
     81 
     82 // Set up the network to use HttpURLConnection as the HTTP client.
     83 Network network = new BasicNetwork(new HurlStack());
     84 
     85 // Instantiate the RequestQueue with the cache and network.
     86 mRequestQueue = new RequestQueue(cache, network);
     87 
     88 // Start the queue
     89 mRequestQueue.start();
     90 
     91 String url ="http://www.myurl.com";
     92 
     93 // Formulate the request and handle the response.
     94 StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
     95         new Response.Listener&lt;String&gt;() {
     96     &#64;Override
     97     public void onResponse(String response) {
     98         // Do something with the response
     99     }
    100 },
    101     new Response.ErrorListener() {
    102         &#64;Override
    103         public void onErrorResponse(VolleyError error) {
    104             // Handle error
    105     }
    106 });
    107 
    108 // Add the request to the RequestQueue.
    109 mRequestQueue.add(stringRequest);
    110 ...
    111 </pre>
    112 
    113 <p>If you just need to make a one-time request and don't want to leave the thread pool
    114 around, you can create the {@code RequestQueue} wherever you need it and call {@code stop()} on the
    115 {@code RequestQueue} once your response or error has come back, using the
    116 {@code Volley.newRequestQueue()} method described in <a href="simple.html">Sending a Simple
    117 Request</a>. But the more common use case is to create the {@code RequestQueue} as a
    118 singleton to keep it running for the lifetime of your app, as described in the next section.</p>
    119 
    120 
    121 <h2 id="singleton">Use a Singleton Pattern</h2>
    122 
    123 <p>If your application makes constant use of the network, it's probably most efficient to
    124 set up a single instance of {@code RequestQueue} that will last the lifetime of your app.
    125 You can achieve this in various ways. The recommended approach is to implement a singleton
    126 class that encapsulates {@code RequestQueue} and other Volley
    127 functionality. Another approach is to subclass {@link android.app.Application} and set up the
    128 {@code RequestQueue} in {@link android.app.Application#onCreate Application.onCreate()}.
    129 But this approach is <a href="{@docRoot}reference/android/app/Application.html">
    130 discouraged</a>; a static singleton can provide the same functionality in a more modular
    131 way. </p>
    132 
    133 <p>A key concept is that the {@code RequestQueue} must be instantiated with the
    134 {@link android.app.Application} context, not an {@link android.app.Activity} context. This
    135 ensures that the {@code RequestQueue} will last for the lifetime of your app, instead of
    136 being recreated every time the activity is recreated (for example, when the user
    137 rotates the device).
    138 
    139 <p>Here is an example of a singleton class that provides {@code RequestQueue} and
    140 {@code ImageLoader} functionality:</p>
    141 
    142 <pre>private static MySingleton mInstance;
    143     private RequestQueue mRequestQueue;
    144     private ImageLoader mImageLoader;
    145     private static Context mCtx;
    146 
    147     private MySingleton(Context context) {
    148         mCtx = context;
    149         mRequestQueue = getRequestQueue();
    150 
    151         mImageLoader = new ImageLoader(mRequestQueue,
    152                 new ImageLoader.ImageCache() {
    153             private final LruCache&lt;String, Bitmap&gt;
    154                     cache = new LruCache&lt;String, Bitmap&gt;(20);
    155 
    156             &#64;Override
    157             public Bitmap getBitmap(String url) {
    158                 return cache.get(url);
    159             }
    160 
    161             &#64;Override
    162             public void putBitmap(String url, Bitmap bitmap) {
    163                 cache.put(url, bitmap);
    164             }
    165         });
    166     }
    167 
    168     public static synchronized MySingleton getInstance(Context context) {
    169         if (mInstance == null) {
    170             mInstance = new MySingleton(context);
    171         }
    172         return mInstance;
    173     }
    174 
    175     public RequestQueue getRequestQueue() {
    176         if (mRequestQueue == null) {
    177             // getApplicationContext() is key, it keeps you from leaking the
    178             // Activity or BroadcastReceiver if someone passes one in.
    179             mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
    180         }
    181         return mRequestQueue;
    182     }
    183 
    184     public &lt;T&gt; void addToRequestQueue(Request&lt;T&gt; req) {
    185         getRequestQueue().add(req);
    186     }
    187 
    188     public ImageLoader getImageLoader() {
    189         return mImageLoader;
    190     }
    191 }</pre>
    192 
    193 <p>Here are some examples of performing {@code RequestQueue} operations using the singleton
    194 class:</p>
    195 
    196 <pre>
    197 // Get a RequestQueue
    198 RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
    199     getRequestQueue();
    200 ...
    201 
    202 // Add a request (in this example, called stringRequest) to your RequestQueue.
    203 MySingleton.getInstance(this).addToRequestQueue(stringRequest);
    204 </pre>
    205