Volley! An Android HTTP library from Google

What is volley?

Unfortunately, those of you who came here hoping to find women in swimsuit hitting a ball on a beach will be disappointed because this article is about Volley, an Android library built by Google to help you with your HTTP requests.

But…Why do you need such a library? – you might ask. Well, because it’s so easy to get HTTP requests wrong that you will certainly fail. And the problem is further enhanced by the sheer number of wrong implementations available on the web.

The naive approach to this problem is to use a HttpUrlConnection on a different thread (remember: no blocking of the UI thread). This approach works just fine and dandy until one day, when you find a crash in the Playstore, it will dawn on you: if a user initiates a HTTP request from an Activity and then closes that Activity, when the server reply arrives, you will manipulate a non-existent Activity.

And that’s just an example of how easily you can get it wrong. Of course there are solutions for this but that implies writing more code and you should always remember: “As a developer, you are your worst enemy”.
So why not let the good folks at Google solve this one for you with Volley? And they do a pretty good job at solving that problem:

  • uses a request queue that allows you to prioritize your requests
  • provides transparent memory and disk cache
  • provides an easy and clean way to use multiple concurrent HTTP requests
  • provides a custom ImageView object for loading images over HTTP

How to use volley?

Here’s an example:

public class MainActivity extends Activity {
  RequestQueue mRequestQueue;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    this.mRequestQueue = Volley.newRequestQueue(this.getContext());

    super.onCreate(savedInstanceState);
    StringRequest rq = new StringRequest(
      Request.Method.GET,
      "https://www.zitec.com",
      new Response.Listener() {
        @Override
        public void onResponse(String response) {
          // TODO Auto-generated method stub		
        }
      }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
          // TODO Auto-generated method stub	
        }
      });
      this.mRequestQueue.add(rq);
  }
	
    @Override
    public void onStop(){
      this.mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
        @Override
        public boolean apply(Request<?> request) {
          return true;
        }
      });
      super.onStop();
    }
}

To initiate a HTTP request, you’ll need a request object that you’ll add to a request queue. You can create that queue when you need it but a better approach would be to create it when your app starts and keep it around, as a static, for further use (but when using statics, make sure you use the application context, not the activity context).

You also might have noticed the cancelAll method being called in the onStop method in our Activity. That is pretty important because, how I said before, you don’t want any “rogue” HTTP requests that were initiated from an Activity that doesn’t exist anymore. And the cancelAll method beats the hell out of having “getActivity() != null” checks all over your code

Custom request objects

Volley toolbox provides a series of request types to help you:

  • StringRequest
  • JsonObjectRequest
  • JsonArrayRequest
  • ImageLoader

All these request types help you by parsing and interpreting the response but, sometimes, you’ll need more: maybe a custom request that interprets the response as you desire. To take care of this problem, you can write your custom request class by extending the Request abstract class.
Here’s a small example of a custom Request class:

public class CustomRequest extends Request {
  private Listener listener;
	
  public CustomRequest(
    int method,
    String url,
    Listener listener,
    ErrorListener errorListener) {
      super(method, url, errorListener);
      this.listener = listener;
    }

    @Override
    protected Response parseNetworkResponse(NetworkResponse response) {
      try {
        String responseData = new String(
          response.data,
          HttpHeaderParser.parseCharset(response.headers)
        );
        return Response.success(
          responseData,
          HttpHeaderParser.parseCacheHeaders(response)
        );
      } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
      }
    }

    @Override
    protected void deliverResponse(String response) {
      listener.onResponse(response);
    }
}

The request class presented in this example does nothing special (you’ll be better of by using a StringRequest) but it demonstrates how easy it is to parse a response and return a Response object.

Caching and paralelization

As I stated before, you’ll encounter several problems when you write your own HTTP loading mechanism, problems that volley just handles in the background. For instance, if you need to make a bunch of HTTP calls, in the naive approach, they will occur one at time, each request waiting for the previous request to finish. To make several requests at the same time, you will need some sort of thread pooling and Volley automatically does this for you in the background with a default of 4 threads.

Volley also supports requests prioritization so you can prioritize the content loading and give a lower priority to your images.

Another problem with the naive approach is that if the user rotates his screen, the activity gets destroyed and recreated so you have to start loading the data all over again. You can, of course, build a caching system but that’s tedious work and Volley has a built-in caching mechanism for that. All you have to do is make sure the server sends the correct cache headers. The caching system that comes out of the box with Volley is pretty fast and is transparent (the user doesn’t have to know about it). On the other hand, there are situations when you may want to build your own caching system, which you can easily do by implementing the Cache interface or the ImageCache interface available in the volley’s toolbox package.

Loading Images

There are also several problems when working with images over the network and one of the most encountered is working with recycled views (like in a list). If you start loading the images and the user scrolls around the list, by the time you finish loading the image, the ImageView will be recycled and will represent the image of a different item in your list. Again, there are solutions to prevent this but it is hard to build such a solution because you have to keep track of your requests, you have to associate each request with an image view and check the results…etc. In a nut shell, it’s more work, you have to write more code, you’ll have to maintain and debug all that code and so on.

Volley offers 2 ways of dealing with issues like this:

  • a cancelation mechanism that allows you to cancel any request
  • the NetworkImageView element

Using the NetworkImageView is easy and all the necessary operations are automatically done for you, in the background. It’s as easy as calling the setImageUrl method of the NetworkImageView object.

Debugging and tracing

The inner workings of the Volley library can be complicated and because they are hidden from the user, it can be pretty tricky to debug. Fortunately, the Volley creators also thought of that and included in the library a debugging and tracking mechanism. To enable this mechanism you’ll need to set the log.tag.Volley system property to VERBOSE by running “adb shell setprop log.tag.Volley VERBOSE”. The Volley logs will appear in LogCat with the tag name Volley so you can create e filter for them.

Conclusion

Of course Volley is not perfect and you should not use it in every situation but it is perfect for API calls and loading small images. If you are planning to use it for large amounts of data, think again. The problem is that volley saves the results in RAM and you will quickly find yourself without memory. For large amounts of data, it’s better to use Download Manager. But that’s another article and soon, we will have a blog post about the darker side of Volley.

Leave a Reply

Subscribe
Notify of
guest
1 Comment
Inline Feedbacks
View all comments
Active News

Very good information.