Home | History | Annotate | Download | only in volley
      1 page.title=Making a Standard Request
      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="#request-image">Request an Image</a></li>
     14   <li><a href="#request-json">Request JSON</a></li>
     15 </ol>
     16 
     17 </div>
     18 </div>
     19 
     20 <a class="notice-developers-video wide" href="https://www.youtube.com/watch?v=yhv8l9F44qo">
     21 <div>
     22     <h3>Video</h3>
     23     <p>Volley: Easy, Fast Networking for Android</p>
     24 </div>
     25 </a>
     26 
     27 <p>
     28 This lesson describes how to use the common request types that Volley supports:</p>
     29 
     30 <ul>
     31   <li>{@code StringRequest}. Specify a URL and receive a raw string in response. See
     32   <a href="requestqueue.html">Setting Up a Request Queue</a> for an example.</li>
     33   <li>{@code ImageRequest}. Specify a URL and receive an image in response.</li>
     34   <li>{@code JsonObjectRequest} and {@code JsonArrayRequest} (both subclasses of
     35   {@code JsonRequest}). Specify a URL and get a JSON object or array (respectively) in
     36   response.</li>
     37 </ul>
     38 
     39 <p>If your expected response is one of these types, you probably won't have to implement a
     40 custom request. This lesson describes how to use these standard request types. For
     41 information on how to implement your own custom request, see <a href="request-custom.html">
     42 Implementing a Custom Request</a>.</p>
     43 
     44 
     45 <h2 id="request-image">Request an Image</h2>
     46 
     47 <p>Volley offers the following classes for requesting images. These classes layer on top
     48 of each other to offer different levels of support for processing images:</p>
     49 
     50 <ul>
     51   <li>{@code ImageRequest}&mdash;a canned request for getting an image at a given URL and
     52   calling back with a decoded bitmap. It also provides convenience features like specifying
     53   a size to resize to. Its main benefit is that Volley's thread scheduling ensures that
     54   expensive image operations (decoding, resizing) automatically happen on a worker thread.</li>
     55 
     56   <li>{@code ImageLoader}&mdash;a helper class that handles loading and caching images from
     57   remote URLs. {@code ImageLoader} is a an orchestrator for large numbers of {@code ImageRequest}s,
     58   for example when putting multiple thumbnails in a {@link android.widget.ListView}.
     59   {@code ImageLoader} provides an in-memory cache to sit in front of the normal Volley
     60   cache, which is important to prevent flickering. This makes it possible to achieve a
     61   cache hit without blocking or deferring off the main thread, which is impossible when
     62   using disk I/O. {@code ImageLoader} also does response coalescing, without which almost
     63   every response handler would set a bitmap on a view and cause a layout pass per image.
     64   Coalescing makes it possible to deliver multiple responses simultaneously, which improves
     65   performance.</li>
     66   <li>{@code NetworkImageView}&mdash;builds on {@code ImageLoader} and effectively replaces
     67   {@link android.widget.ImageView} for situations where your image is being fetched over
     68   the network via URL. {@code NetworkImageView} also manages canceling pending requests if
     69   the view is detached from the hierarchy.</li>
     70 </ul>
     71 
     72 <h3>Use ImageRequest</h3>
     73 
     74 <p>Here is an example of using {@code ImageRequest}. It retrieves the image specified by
     75 the URL and displays it in the app. Note that this snippet interacts with the
     76 {@code RequestQueue} through a singleton class (see <a href="{@docRoot}
     77 training/volley/requestqueue.html#singleton">Setting Up a RequestQueue</a> for more discussion of
     78 this topic):</p>
     79 
     80 <pre>
     81 ImageView mImageView;
     82 String url = "http://i.imgur.com/7spzG.png";
     83 mImageView = (ImageView) findViewById(R.id.myImage);
     84 ...
     85 
     86 // Retrieves an image specified by the URL, displays it in the UI.
     87 ImageRequest request = new ImageRequest(url,
     88     new Response.Listener&lt;Bitmap&gt;() {
     89         &#64;Override
     90         public void onResponse(Bitmap bitmap) {
     91             mImageView.setImageBitmap(bitmap);
     92         }
     93     }, 0, 0, null,
     94     new Response.ErrorListener() {
     95         public void onErrorResponse(VolleyError error) {
     96             mImageView.setImageResource(R.drawable.image_load_error);
     97         }
     98     });
     99 // Access the RequestQueue through your singleton class.
    100 MySingleton.getInstance(this).addToRequestQueue(request);</pre>
    101 
    102 
    103 <h3>Use ImageLoader and NetworkImageView</h3>
    104 
    105 <p>You can use {@code ImageLoader} and {@code NetworkImageView} in concert to efficiently
    106 manage the display of multiple images, such as in a {@link android.widget.ListView}. In your
    107 layout XML file, you use {@code NetworkImageView} in much the same way you would use
    108 {@link android.widget.ImageView}, for example:</p>
    109 
    110 <pre>&lt;com.android.volley.toolbox.NetworkImageView
    111         android:id=&quot;&#64;+id/networkImageView&quot;
    112         android:layout_width=&quot;150dp&quot;
    113         android:layout_height=&quot;170dp&quot;
    114         android:layout_centerHorizontal=&quot;true&quot; /&gt;</pre>
    115 
    116 <p>You can use {@code ImageLoader} by itself to display an image, for example:</p>
    117 
    118 <pre>
    119 ImageLoader mImageLoader;
    120 ImageView mImageView;
    121 // The URL for the image that is being loaded.
    122 private static final String IMAGE_URL =
    123     "http://developer.android.com/images/training/system-ui.png";
    124 ...
    125 mImageView = (ImageView) findViewById(R.id.regularImageView);
    126 
    127 // Get the ImageLoader through your singleton class.
    128 mImageLoader = MySingleton.getInstance(this).getImageLoader();
    129 mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
    130          R.drawable.def_image, R.drawable.err_image));
    131 </pre>
    132 
    133 <p>However, {@code NetworkImageView} can do this for you if all you're doing is populating
    134 an {@link android.widget.ImageView}. For example:</p>
    135 
    136 <pre>
    137 ImageLoader mImageLoader;
    138 NetworkImageView mNetworkImageView;
    139 private static final String IMAGE_URL =
    140     "http://developer.android.com/images/training/system-ui.png";
    141 ...
    142 
    143 // Get the NetworkImageView that will display the image.
    144 mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
    145 
    146 // Get the ImageLoader through your singleton class.
    147 mImageLoader = MySingleton.getInstance(this).getImageLoader();
    148 
    149 // Set the URL of the image that should be loaded into this view, and
    150 // specify the ImageLoader that will be used to make the request.
    151 mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
    152 </pre>
    153 
    154 <p>The above snippets access the {@code RequestQueue} and the {@code ImageLoader}
    155 through a singleton class, as described in <a href="{@docRoot}training/volley/requestqueue.html#singleton">
    156 Setting Up a RequestQueue</a>. This approach ensures that your app creates single instances of
    157 these classes that last the lifetime of your app. The reason that this is important for
    158 {@code ImageLoader} (the helper class that handles loading and caching images) is that
    159 the main function of the in-memory cache is to allow for flickerless rotation. Using a
    160 singleton pattern allows the bitmap cache to outlive the activity. If instead you create the
    161 {@code ImageLoader} in an activity, the {@code ImageLoader} would be recreated along with
    162 the activity every time the user rotates the device. This would cause flickering.</p>
    163 
    164 <h4 id="lru-cache">Example LRU cache</h4>
    165 
    166 <p>The Volley toolbox provides a standard cache implementation via the
    167 {@code DiskBasedCache} class. This class caches files directly onto the hard disk in the
    168 specified directory. But to use {@code ImageLoader}, you should provide a custom
    169 in-memory LRU bitmap cache that implements the {@code ImageLoader.ImageCache} interface.
    170 You may want to set up your cache as a singleton; for more discussion of this topic, see
    171 <a href="{@docRoot}training/volley/requestqueue.html#singleton">
    172 Setting Up a RequestQueue</a>.</p>
    173 
    174 <p>Here is a sample implementation for an in-memory {@code LruBitmapCache} class.
    175 It extends the {@link android.support.v4.util.LruCache} class and implements the
    176 {@code ImageLoader.ImageCache} interface:</p>
    177 
    178 <pre>
    179 import android.graphics.Bitmap;
    180 import android.support.v4.util.LruCache;
    181 import android.util.DisplayMetrics;
    182 import com.android.volley.toolbox.ImageLoader.ImageCache;
    183 
    184 public class LruBitmapCache extends LruCache&lt;String, Bitmap&gt;
    185         implements ImageCache {
    186 
    187     public LruBitmapCache(int maxSize) {
    188         super(maxSize);
    189     }
    190 
    191     public LruBitmapCache(Context ctx) {
    192         this(getCacheSize(ctx));
    193     }
    194 
    195     &#64;Override
    196     protected int sizeOf(String key, Bitmap value) {
    197         return value.getRowBytes() * value.getHeight();
    198     }
    199 
    200     &#64;Override
    201     public Bitmap getBitmap(String url) {
    202         return get(url);
    203     }
    204 
    205     &#64;Override
    206     public void putBitmap(String url, Bitmap bitmap) {
    207         put(url, bitmap);
    208     }
    209 
    210     // Returns a cache size equal to approximately three screens worth of images.
    211     public static int getCacheSize(Context ctx) {
    212         final DisplayMetrics displayMetrics = ctx.getResources().
    213                 getDisplayMetrics();
    214         final int screenWidth = displayMetrics.widthPixels;
    215         final int screenHeight = displayMetrics.heightPixels;
    216         // 4 bytes per pixel
    217         final int screenBytes = screenWidth * screenHeight * 4;
    218 
    219         return screenBytes * 3;
    220     }
    221 }
    222 </pre>
    223 
    224 <p>Here is an example of how to instantiate an {@code ImageLoader} to use this
    225 cache:</p>
    226 
    227 <pre>
    228 RequestQueue mRequestQueue; // assume this exists.
    229 ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
    230             LruBitmapCache.getCacheSize()));
    231 </pre>
    232 
    233 
    234 <h2 id="request-json">Request JSON</h2>
    235 
    236 <p>Volley provides the following classes for JSON requests:</p>
    237 
    238 <ul>
    239   <li>{@code JsonArrayRequest}&mdash;A request for retrieving a
    240   {@link org.json.JSONArray}
    241   response body at a given URL.</li>
    242   <li>{@code JsonObjectRequest}&mdash;A request for retrieving a
    243   {@link org.json.JSONObject}
    244   response body at a given URL, allowing for an optional
    245   {@link org.json.JSONObject}
    246   to be passed in as part of the request body.</li>
    247 </ul>
    248 
    249 <p>Both classes are based on the common base class {@code JsonRequest}. You use them
    250 following the same basic pattern you use for other types of requests. For example, this
    251 snippet fetches a JSON feed and displays it as text in the UI:</p>
    252 
    253 <pre>
    254 TextView mTxtDisplay;
    255 ImageView mImageView;
    256 mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
    257 String url = "http://my-json-feed";
    258 
    259 JsonObjectRequest jsObjRequest = new JsonObjectRequest
    260         (Request.Method.GET, url, null, new Response.Listener&lt;JSONObject&gt;() {
    261 
    262     &#64;Override
    263     public void onResponse(JSONObject response) {
    264         mTxtDisplay.setText("Response: " + response.toString());
    265     }
    266 }, new Response.ErrorListener() {
    267 
    268     &#64;Override
    269     public void onErrorResponse(VolleyError error) {
    270         // TODO Auto-generated method stub
    271 
    272     }
    273 });
    274 
    275 // Access the RequestQueue through your singleton class.
    276 MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
    277 </pre>
    278 
    279 For an example of implementing a custom JSON request based on
    280 <a href="http://code.google.com/p/google-gson/">Gson</a>, see the next lesson,
    281 <a href="request-custom.html">Implementing a Custom Request</a>.
    282