A few days ago, during the Google I/O, Ficus Kilkpatrick presented Volley. Volley is an HTTP library that aims at removing lots of boilerplate code, simplifying the handling of images in lists, be faster, abstract the complexity of one or another HTTP client.
The presentation is here: https://developers.google.com/events/io/sessions/325304728
The code is here: https://android.googlesource.com/platform/frameworks/volley/
git clone https://android.googlesource.com/platform/frameworks/volley
clones a valid Eclipse project ready to integrate in your app.
This post is a quick demo of the basic functions of Volley. It demonstrates the use of Volley with the JSON RESTful API from Sna.pr (see http://developers.sna.pr/docs/api_basics/). It will fetch JSON data from Sna.pr, extract the URLs to the images, display thumbnails in a GridView, and display the large image in another Activity.
All the code used in this demo is available here: https://github.com/smaspe/SnaprVolley.
Initialization
Volley relies on a RequestQueue
, that handle a queue of request, and on an ImageLoader
, that is in charge of loading the images. We need one of each
public static ImageLoader mImageLoader;
public static RequestQueue mRequestQueue;
We also need to initialize them. The queue needs a Context
, the ImageLoader
needs an ImageCache
. Here, I use a basic wrapper to LruCache<String, Bitmap>
.
mRequestQueue = Volley.newRequestQueue(this);
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLru(64000));
The initialization is done in the onCreate()
of the first activity.
Getting a JSONObject
The basic query on the Snapr API is search. Making a request using Volley is pretty straightforward. Simply add a Request
object on the RequestQueue
, add a Listener
and that’s it. In particular, the JsonObjectRequest
returns a JSONObject
in a callback.
mRequestQueue.add(new JsonObjectRequest(SNAPR_URL, null,
new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// TODO handle the response
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}));
The JSONObject
received is handled in the onResponse
method. (The Sna.pr API describes the detailed format of the response.)
@Override
public void onResponse(JSONObject response) {
if (!response.optBoolean("success", false)) {
Log.w(TAG, "Request failed");
try {
Log.w(TAG, "Details " + response.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
return;
}
JSONArray images = null;
try {
images = response.getJSONObject("response")
.getJSONArray("photos");
} catch (JSONException e) {
e.printStackTrace();
}
if (images != null) {
for (int i = 0; i < images.length(); i++) {
JSONObject object = images.optJSONObject(i);
if (object == null) {
continue;
}
String imageUrl = "http://media-server"
+ object.optString("server_id") + ".snapr.us/thm2/"
+ object.optString("secret") + "/"
+ object.optString("id") + ".jpg";
imageUrlAdapter.add(imageUrl);
}
}
}
The URL is passed to the ImageUrlAdapter
, which is a simple ArrayAdapter<String>
that populates a GridView
.
Getting an image in a GridView
The ImageUrlAdapter
populates a GridView
(or any AdapterView
) with NetworkImageView
. This is a class provided by Volley to put images from the network into an ImageView
. It actually extends ImageView
, meaning you can use it anywhere you use an ImageView
. It is extremely simple to use. The only code in the adapter is the getView
.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
NetworkImageView imageView;
if (convertView == null) {
imageView = new NetworkImageView(getContext());
} else {
imageView = (NetworkImageView) convertView;
}
String url = getItem(position);
imageView.setImageUrl(url, MainActivity.mImageLoader);
return imageView;
}
The only new thing here is imageView.setImageUrl(url, MainActivity.mImageLoader);
That’s it. Nothing more is required.
Further stuff
The demo project also contains the onItemClickListener
and the second activity to display the large image. Both are not discussed here as no other feature is used.
The BitmapLru
is the simplest ImageCache
possible. It is only a wrapper around LruCache<String, Bitmap>
.
Using POST
, adding a body and headers, custom Request
objects are be discussed in the next post.