Asynchronous HTTP Requests in Android Using Volley
Volley is the new Swiss Army Knife of Android Developers, it provides some nice utilities which makes the networking for Android apps easier and faster. The good thing about Volley is that it abstracts away the low level details of what HTTP client library is being used under the hood and helps you focus on writing nice and clean RESTful HTTP requests. Additionally all requests in Volley are executed asynchronously on a different thread without blocking your “main thread”.
What are the features that Volley provides?
Important features of the Volley library:
- A high level API to make asynchronous RESTful HTTP requests
- An elegant and robust Request queue
- An extensible architecture which allows developers to implement custom request and response handling mechanism
- Ability to use external HTTP client library
- Robust request caching policy
- Custom views to load and cache images from Network (
NetworkImageView
,ImageLoader
etc)
Why use asynchronous HTTP requests?
In Android it is always a good practice to make HTTP requests asynchronously, in fact from HoneyComb onwards it is no longer just a “good practice”, you must make HTTP requests asynchronously off the main thread or else you’ll get this nasty exception android.os.NetworkOnMainThreadException
. Blocking the main thread has some serious consequences, it hampers UI rendering, harmful to smooth user experience and above all it can cause dreaded ANR (Application Not Responding). To avoid all these pitfalls you as a developer should always ensure that your HTTP requests are on a different thread.
How to use Volley
We are going to cover the following items in this blog post, by the end of it you should be able to have a clear understanding of Volley and how to use it in your application.
- Installing and using Volley as a library project
- Using Request Queue
- Making asynchronous JSON and String HTTP requests
- Cancelling requests
- Retrying failed requests, customizing request Timeout
- Setting Request Headers (HTTP headers)
- Using cookies
- Error Handling
Installing and using Volley as a library project
Volley is part of AOSP and right now it is not being distributed as a JAR, the easiest way to include Volley to your project is to clone the Volley repository and set it as a library project.
Using as a library project
Git clone the repository using the following command and then import it as Android library project:
1
|
|
Using as a JAR
Clone the repository as shown above and then run the following commands to export it as JAR and after that add the JAR file to your project’s /libs
folder:
1 2 3 4 |
|
Using Request Queue
All requests in Volley are placed in a queue first and then processed, here is how you will be creating a request queue:
1
|
|
Ideally you should have one centralized place for your Queue, and the best place to initialize queue is in your Application class. Here is how this can be done:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
Making asynchronous HTTP requests
Volley provides the following utility classes which you can use to make asynchronous HTTP requests:
- JsonObjectRequest — To send and receive JSON Object from the Server
- JsonArrayRequest — To receive JSON Array from the Server
- StringRequest — To retrieve response body as String (ideally if you intend to parse the response by yourself)
Note: To send parameters in request body you need to override either getParams()
or getBody()
method of the request classes (as required) described below.
JsonObjectRequest
This class can be used to send and receive JSON object. An overloaded constructor of this class allows to set appropriate request method (DELETE, GET, POST and PUT). This is the class which you should be using frequently if you are working with a RESTful backend. The following examples show how to make GET and POST requests.
Using HTTP GET method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Using HTTP POST method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
JsonArrayRequest
This class can be used to retrieve JSON array but not JSON object and only HTTP GET is supported as of now. As it supports only GET, so if you are to specify some querystring parameters then append those in the URL itself. The constructor does not accept request parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
StringRequest
This class can be used to retrieve the response from server as String, ideally you should use this class when you intend to parse the response by yourself, e.g. if it is XML. It also provides overloaded constructors to further customize your request.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Setting a priority to the request is possible, this may be desirable in some cases where you want to move certain requests higher up in the order. The requests are processed from higher priorities to lower priorities, in FIFO order. To set a priority you need to override the getPriority()
method of the request class. The current available priorities are – Priority.LOW
, Priority.NORMAL
, Priority.HIGH
and Priority.IMMEDIATE
.
Cancelling requests
Volley provides powerful APIs to cancel pending or ongoing requests, one reason when you need to do this is if user rotates his device while a request is ongoing you need to cancel that because the Activity is going be restarted. The easiest way to cancel a request is to call the cancelAll(tag)
method of the request queue, this will only work if you have set a tag on the request object before adding it to the queue. The ability to tag requests allows you to cancel all pending requests for that tag in one method call.
Adding a request to the queue using a tag:
1
|
|
As per the ApplicationController class shown above, this is how you’ll add the request to the queue:
1
|
|
Cancelling all requests with the specified tag:
1
|
|
As per the ApplicationController class shown above, this is how you’ll cancel the requests:
1
|
|
Retrying failed requests and customizing request Timeout
There is no direct way to specify request timeout value in Volley, but there is a workaround, you need to set a RetryPolicy on the request object. The DefaultRetryPolicy
class takes an argument called initialTimeout, this can be used to specify a request timeout, make sure the maximum retry count is 1 so that volley does not retry the request after the timeout has been exceeded.
1
|
|
If you want to retry failed requests (due to timeout) you can specify that too using the code above, just increase the retry count. Note the last argument, it allows you to specify a backoff multiplier which can be used to implement “exponential backoff” that some RESTful services recommend.
Setting Request Headers (HTTP headers)
Sometimes it is necessary to add extra headers to the HTTP requests, one common case is to add an “Authorization” header for HTTP Basic Auth. Volley Request class provides a method called getHeaders()
which you need to override to add your custom headers if necessary.
Adding custom headers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Using cookies
There is no direct API through which you can set cookies in Volley. This makes sense because the core philosophy of Volley is to provide clean APIs to write RESTful HTTP requests, these days most of the RESTful API providers prefer authentication tokens instead of cookies. Using cookies in Volley is a bit more involed process and not very straight forward.
Here is a modified version of the getRequestQueue()
method of our ApplicationController class shown above, also contains the rough code required to set a cookie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Error Handling
As you have seen in the above code examples when you create a request object in Volley you need to specify an error listener, Volley invokes the onErrorResponse
callback method of that listener passing an instance of the VolleyError
object when there is an error while performing the request.
The following is the list of exceptions in Volley:
- AuthFailureError — If you are trying to do Http Basic authentication then this error is most likely to come.
- NetworkError — Socket disconnection, server down, DNS issues might result in this error.
- NoConnectionError — Similar to NetworkError, but fires when device does not have internet connection, your error handling logic can club
NetworkError
andNoConnectionError
together and treat them similarly. - ParseError — While using
JsonObjectRequest
orJsonArrayRequest
if the received JSON is malformed then this exception will be generated. If you get this error then it is a problem that should be fixed instead of being handled. - ServerError — The server responded with an error, most likely with 4xx or 5xx HTTP status codes.
- TimeoutError — Socket timeout, either server is too busy to handle the request or there is some network latency issue. By default Volley times out the request after 2.5 seconds, use a RetryPolicy if you are consistently getting this error.
You can use a simple helper like the following to display appropriate message when one of these exceptions occurs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
|
Conclusion
Volley is really a nice library and you should seriously consider giving this a try. It will help you simplify your network requests and also add a ton of additional benefits.
I understand that it’s a tl;dr post, actually I tried to be as comprehensive as possible, I am planning to come up with another post about image loading using Volley and some gotchas that I noticed while using the library in one of my projects, till then stay tuned.
Thanks for reading, I hope you enjoyed this :–)
References
- NetworkOnMainThreadException — http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
- Application — http://developer.android.com/reference/android/app/Application.html