1page.title=Setting Up a RequestQueue 2 3trainingnavtop=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 30Volley'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} 34as 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 39of the requests, and a cache to handle caching. There are standard implementations of these 40available in the Volley toolbox: {@code DiskBasedCache} provides a one-file-per-response 41cache with an in-memory index, and {@code BasicNetwork} provides a network transport based 42on 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} 45must be initialized with the HTTP client your app is using to connect to the network. 46Typically 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 50lower than API Level 9 (Gingerbread). Prior to Gingerbread, {@link java.net.HttpURLConnection} 51was unreliable. For more discussion of this topic, see 52<a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html"> 53Android'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 59Android the device is running and choose the appropriate HTTP client, for example:</p> 60 61<pre> 62HttpStack stack; 63... 64// If the device is running a version >= Gingerbread... 65if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 66 // ...use HttpURLConnection for stack. 67} else { 68 // ...use AndroidHttpClient for stack. 69} 70Network 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> 77RequestQueue mRequestQueue; 78 79// Instantiate the cache 80Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap 81 82// Set up the network to use HttpURLConnection as the HTTP client. 83Network network = new BasicNetwork(new HurlStack()); 84 85// Instantiate the RequestQueue with the cache and network. 86mRequestQueue = new RequestQueue(cache, network); 87 88// Start the queue 89mRequestQueue.start(); 90 91String url ="http://www.myurl.com"; 92 93// Formulate the request and handle the response. 94StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 95 new Response.Listener<String>() { 96 @Override 97 public void onResponse(String response) { 98 // Do something with the response 99 } 100}, 101 new Response.ErrorListener() { 102 @Override 103 public void onErrorResponse(VolleyError error) { 104 // Handle error 105 } 106}); 107 108// Add the request to the RequestQueue. 109mRequestQueue.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 114around, 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 117Request</a>. But the more common use case is to create the {@code RequestQueue} as a 118singleton 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 124set up a single instance of {@code RequestQueue} that will last the lifetime of your app. 125You can achieve this in various ways. The recommended approach is to implement a singleton 126class that encapsulates {@code RequestQueue} and other Volley 127functionality. Another approach is to subclass {@link android.app.Application} and set up the 128{@code RequestQueue} in {@link android.app.Application#onCreate Application.onCreate()}. 129But this approach is <a href="{@docRoot}reference/android/app/Application.html"> 130discouraged</a>; a static singleton can provide the same functionality in a more modular 131way. </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 135ensures that the {@code RequestQueue} will last for the lifetime of your app, instead of 136being recreated every time the activity is recreated (for example, when the user 137rotates 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<String, Bitmap> 154 cache = new LruCache<String, Bitmap>(20); 155 156 @Override 157 public Bitmap getBitmap(String url) { 158 return cache.get(url); 159 } 160 161 @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 <T> void addToRequestQueue(Request<T> 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 194class:</p> 195 196<pre> 197// Get a RequestQueue 198RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()). 199 getRequestQueue(); 200... 201 202// Add a request (in this example, called stringRequest) to your RequestQueue. 203MySingleton.getInstance(this).addToRequestQueue(stringRequest); 204</pre> 205