| 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<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>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<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> |