| 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://www.youtube.com/watch?v=yhv8l9F44qo"> | |
| <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 preferred HTTP client.</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 an {@link java.net.HttpURLConnection}.</p> | |
| <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.example.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> |