Executive summary: Retrofit 2 and Volley are both great networking libraries for modern Android apps, but each has its own strengths that are worth weighing for critical projects. Use Retrofit if your use-case is a standard REST API with JSON responses and not too many custom requirements in terms of caching, request prioritization, retries, etc. Use Volley if you have unusual / fine-grained requirements, or if you anticipate needing a lot of flexibility from your networking layer in the future at the cost of more code. Use neither if you're downloading large files or streaming -- for that, use DownloadManager
instead.
As Android developers we have 2 great networking libraries available to us: Square's Retrofit and Google's Volley. Naturally, when we have 2 equally good-looking choices we want to take the right decision -- based on actual use-cases and anticipated growth of our apps in the future. In particular, I would recommend not selecting based on how many boxes these libraries check off on a list of arbitrary features; instead focus on what you really need and choose the one that provides the most robust support for those.
I've used Retrofit extensively for a year and Volley in a somewhat limited way a few months after it was released, so I think I have something to offer in terms of the comparison here. This article is targeted at someone completely new to these libraries. I will not focus too much on how to go about using these libraries, since that is covered well elsewhere. I have however linked to sample code / documentation throughout, so you can use this post as an index.
The details here are updated as of December 2015. Please leave a comment if you find any factual errors / critical omissions, especially about Volley.
Ease-of-use
Retrofit is dead-simple to use. It essentially lets you treat API calls as simple Java method calls, so you only define which URLs to hit and the types of the request/response parameters as Java classes. The entire network call + JSON/XML parsing is completely handled by it (with help from Gson for JSON parsing), along with support for arbitrary formats with pluggable serialization / deserialization. Documentation is great and the community is huge. I'll just paste some code here so you get a feel for what I'm talking about.
// Retrofit turns your HTTP API into a Java interface
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
// the Retrofit class generates an implementation of the above interface
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
// each Call from the created GitHubService can make a synchronous or
// asynchronous HTTP request to the remote webserver
Call<List<Repo>> repos = service.listRepos("octocat");
// let's use the Call asynchronously
call.enqueue(new Callback<List<Contributor>>() {
@Override void onResponse(Response<List<Contributor>> contributors) {
// ...
}
@Override void onFailure(Throwable t) {
// ...
}
});
Volley involves a little more boilerplate in general. Out-of-the-box, the only response types supported are String
, Image
, JSONObject
, and JSONArray
. To avoid the burden of unpacking JSONObject
s yourself and use it like Retrofit, you need to include this GsonRequest<T>
class, which basically represents a request whose response is converted to type T
by Gson. There is also no built-in XML support, but I expect you can build that yourself too. Official documentation on Volley is somewhat lacking, although there are a few basic tutorials by Google, unofficial Javadocs, and a large, scattered body of knowledge over on StackOverflow. Here's a short code sample (note: this is for a raw String
response; if you want a response of arbitrary type, like List<Contributor>
in the Retrofit example, you'll need to implement GsonRequest<T>
yourself):
// instantiate the RequestQueue
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// request a string response asynchronously from the provided URL
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// ...
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// ...
}
});
// add the request to the RequestQueue
queue.add(stringRequest);
Both Retrofit and Volley support async requests with minimal code, as we saw above, so they're equally great there. No more AsyncTask
s + manual JSON parsing -- which is a huge win for the maintainability of your code!
Image loading
Retrofit does not come with support for loading images from the network by itself. Another small library called Picasso is recommended for this. I really don't consider this a drawback because (a) Picasso is just as easy to use as Retrofit, and, (b) it avoids over-burdening the core library and bloating your APK if you don't need image loading features -- indeed this might be considered an advantage if you're looking for a smaller library over ease-of-use for images.
Volley has rudimentary support for image loading, which suffices for use-cases with a small number of images and not too many feature requirements. For most non-trivial cases, however, you'll want to use Glide instead.
So in this category it really comes down to Picasso vs Glide. Both libraries have a nearly identical API and feature set. The main differences are that:
- Glide caches images after resizing so it loads faster and uses less memory (demo), but may end up saving multiple copies of the same image at different sizes. Picasso saves the full image and resizes it on load, which is less memory- and CPU-efficient, but if you're displaying images at several sizes it will use up less disk space.
- Glide supports GIFs and locally-stored videos, Picasso doesn't.
Performance and caching
Both libraries use thread pools and execute multiple requests in parallel, and both support the venerable OkHttp library[1].
Retrofit: caching should "just work" if your server sets the correct cache control headers. If not, or if you're trying to do something unusual, you may be out of luck. The only lever you can turn here is your HTTP client layer (OkHttp, HttpUrlConnection, etc), as in this example.
Volley definitely has a more elaborate and flexible caching mechanism. Glide leverages it to great effect for caching bitmaps.
Request prioritization, cancellation and retrying
Retrofit: does not support setting priority, although there are hacks available; supports cancellation since v2 (which is in late beta now); supports manual request retries.
Volley: supports prioritization with a little extra code; supports cancellation and customizable retry with exponential backoff out-of-the-box.
POST requests + multipart uploads
Retrofit has full support for POST requests and multipart file uploads, with a sweet API to boot.
Volley supports POST requests but you'll have to convert your Java objects to JSONObject
s yourself (e.g., with Gson). Also supports multipart requests but you need to add these additional classes or equivalent. The experience is not as polished as with Retrofit, but probably a bit more flexible as a result.
Extensibility
Retrofit has a well-designed, intuitive API with a small number of extension points for common use-cases, e.g., for (de)serialization and request threading. Jake Wharton discusses Retrofit 2's extension points in his great talk from Droidcon NYC 2015.
Volley on the other hand is very open to extension and even relies on that fact for common features like request priority, setting up a global long-lived RequestQueue
, and bitmap caching. The success of Glide is proof of Volley's great extensibility.
Dynamic URLs
Retrofit supports dynamic URLs since v2. By "dynamic" I mean the URL is not known until runtime, as is the case with pagination in Github's API, which sends previous/next page links in the response headers and the URLs can be unguessable.
Volley obviously supports dynamic URLs, as we saw in the very first example above, the URL being the second parameter in the StringRequest
constructor.
Large file downloads / streaming
Neither Retrofit nor Volley is designed for this, and you will probably run into out-of-memory issues if you try. Both recommend using DownloadManager
instead, which supports resuming and progress notifications.
OkHttp is a low-level HTTP client library with a boatload of features and great flexibility. Since Android 4.4, it's also the default engine underpinning Android's HttpUrlConnection. ↩︎