Android Networking II: OkHttp, Retrofit, Moshi and Picasso

A series of articles digging in the Android networking libraries.

Prologue

This is the second article of a series:

Assumptions

Motivation

There’s something that probably you can’t avoid in an Android project: Networking. Whether you are loading images, requesting data from an API server or getting a single byte from internet, you are doing networking.

No doubt there are a lot of good libraries out there and the wheel doesn’t need to be reinvented, but given how complex and omnipresent networking is on Android, one common question Android developers face when they start researching about networking is which libraries should I use? what’s the difference? what do I actually need?

On one side, you have a bunch of small libraries focused on solving one specific problem that you can stack on top of each other and combine them to achieve your needs.

On the other side, you have some libraries that look more like a Swiss knife and can handle a lot of different scenarios related with networking. From HTTP client to image loading, and of course, REST helper.

The root of so many great networking libraries is that the offered options in the Android framework are not great and they were a mess to deal with in the old days (Eclair, Froyo and Gingerbread). You had to write a lot of boilerplate code each time you were doing requests, and probably you’ll be doing a sub-optimal (a.k.a. poor) job. This was the ideal scenario to solve once and for all a really big and important problem, so a lot of libraries started to appear and evolve.

In the old days, networking in Android was a nightmare. Nowadays the problem is to find out which solution fits better the project’s necessities.

This article talks about four libraries that play well with each other and will help you to cover most of your needs: OkHttp, Retrofit, Moshi and Picasso.

What is OkHttp?

OkHttp is a modern, fast and efficient Http client which supports HTTP/2 and SPDY. Reading how many things OkHttp does, is a good way to understand how hard is to do networking: Connection pooling, gziping, caching, recovers from network problems, sync and async calls, redirects, retries … and so on.

OkHttp is a very capable networking tool out of the box, without the need of any REST library (Retrofit, Volley…) and probably it is the library most developers would choose if they could only include one library in their projects.

OkHttp is an modern, fast and efficient Http client which supports HTTP/2 and SPDY and sits on top of Okio

OkHttp sits on top of Okio, a library that complements java.io and java.nio to make it much easier to access, store, and process your data. It provides fast I/O and resizable buffers.

One of the authors of Okio described it as the IO layer from OkHttp ripped out and made a standalone project.

OkHttp depends on Okio (so you’ll have Okio in your project as well), but Okio can be used by its own.

Okio is the IO layer from OkHttp ripped out and made a standalone project

What is Retrofit?

Retrofit is a type-safe REST adapter that makes easy common networking tasks. Retrofit turns your REST API into a Java interface and uses annotations to describe the HTTP request. Retrofit takes care of URL manipulation, requesting, loading, caching, threading, synchronization... It allows sync and async calls.

It is important to realize that since Retrofit 2.0:

  • Retrofit depends on OkHttp, which depends on Okio. Using Retrofit 2.0 means you are using OkHttp and Okio.
  • Gson is not bundled anymore with Retrofit. Retrofit can only deserialize (out of the box) HTTP bodies into OkHttp’s ResponseBody type.
  • There are several converters that can be added to Retrofit to support different types as XML or JSON.

Retrofit is among the most used and most famous REST clients in Android.

Retrofit is a REST client that sits on top of OkHttp and makes very easy common networking tasks.

One of the authors of Retrofit described what Retrofit does as taking Java interfaces, reading its annotations, and figuring out how to make http calls.

What is Moshi?

Moshi is a modern JSON library. It makes it easy to parse JSON into Java objects. Moshi comes from the same guys behind Okio, OkHttp, Retrofit and Picasso and works really well with them.

The guys that are behind Moshi have been behind Gson as well, and you can tell that, given the similarities between them. Moshi uses the same streaming and binding mechanisms as Gson. However, Moshi has important differences with Gson, as it has fewer built-in type adapter and configuration options (no field naming strategy, versioning, instance creators or long serialization policy).

In order to use Moshi, we need the Moshi converter that is what helps Moshi and Retrofit to work together.

The reason Moshi it is the converter we are using here, is not because is better than Gson or Jackson, but because it is new, simple and made by the same guys that develop all the other libraries in this article and they play very nice with each other (more details in this video).

Square offers the next converters to use with Retrofit:

Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml

Apart from that, you can create your converter implementing the Converter.Factory interface.

What is Picasso?

Image loading in Android is common and complex. Threading, requesting, transformations, memory management, caches…Probably we could write an entire article about it. The good news is there are so many good libraries out there that most of us will never realize how hard it is.

Picasso is a powerful image downloading for Android providing features as automatic memory and disk caching, complex image transformations with minimal memory use, handling ImageView recycling and download cancellation in an adapter, image resizing…

Picasso is among the most used and famous image loading libraries.

Picasso is famous for its performance and an extremely simple and clean API that has inspired many other libraries. Picasso allows you to load images from assets, resources, files, URLs and content providers. A placeholder, error image, size, scale type and other stuff can be define as well.

Picasso 2.5.2 doesn’t support GIFs.

Picasso is efficient, powerful, light and easy to use.

Gradle dependencies in Android Studio

Dependencies between libraries goes like:

  • Moshi Converter depends on Retrofit and Moshi.
  • Moshi depends on Okio.
  • Retrofit depends on OkHttp.
  • OkHttp depends on Okio.
  • Picasso doesn’t depend on any library. It uses OkHttp if you include the dependency but it is optional.

In order to use all of them, it’s just necessary to add the next dependencies to the app’s build.gradle file.

compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.retrofit2:converter-moshi:2.3.0'

In case you don’t use all of the libraries, choose the ones you want to use having in mind the dependencies mentioned before.

compile 'com.squareup.okio:okio:1.13.0'
compile 'com.squareup.moshi:moshi:1.5.0'
compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-moshi:2.3.0'

Note: The versions may be different as they are updated. Try to avoid + syntax on version numbers as recommended to avoid breaking builds.

OkHttp set up

OkHttp has strong defaults on purpose. By default, it’s really fast and robust, so app developers don’t need to go through set ups. Transparent gzip, http/2, ssl… are turned on and are automatic.

Probably some of you would be interested in…

private int connectTimeout = 10_000;
private int readTimeout = 10_000;
private int writeTimeout = 10_000;

Those defaults can be modified via setters among a lot of other configs. Remember OkHttp can be used as a standalone for networking so it’s very powerful.

Retrofit set up

Performance and simplicity are the things tha make Retrofit (probably) the most used REST client on Android. Let’s see how it works.

Services

You can consider a service declaration as a list of related API endpoints.

/**
* Retrofit services
*/
public interface APIService
{
@GET("55973508b0e9e4a71a02f05f")
Call<DummyObject> getDummyObject();
}

Note: The numbers in brackets are URL paths.

Calls

A call is an object that represents a request. you can execute it in a synchronous or an asynchronous way.

/**
*
@return a {@link DummyObject} {@link Call}
*/
public static Call<DummyObject> getDummyObjectCall()
{
return
new
Retrofit
.Builder()
.baseUrl("http://www.mocky.io/v2/")
.addConverterFactory
(MoshiConverterFactory.create())
.build()
.create(APIService.class)
.getDummyObject();
}

In the code above, we are creating the REST client and setting the base URL, the converter (Moshi) and the service. Once we have the service, we ask for the call to that service.

As we mentioned before, Retrofit does not bundle Gson anymore. By default, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type and it can only accept its RequestBody type for@Body.

That’s the reason we are setting the Moshi converter factory to use Moshi as the converter.

URL resolving is not trivial and has changed in Retrofit 2.0. We have two concepts:

  • Base URL: Belongs to the client (Retrofit). It is specified with the method baseURL(String baseUrl).
  • Relative path: Belongs to the service. It is specified in the service declaration via annotations.

If the relative path starts with “/”, Retrofit will only use the hostname (www.example.com) of the base URL.

If the relative path starts without “/”, Retrofit will use as the base URL the String until the last “/” or the hostname (www.example.com) if any.

Examples:

Rule of thumb:

  • Use just the hostname as the base URL (www.example.com).
  • Specify in the service the relative path. It doesn’t matter if it starts with “/” or not.

Note: If you declare a full URL in the service, the base URL will be ignored.

Requests

// Blocking call that can’t be executed on the main thread.
Response<DummyObject> response =
ApiRequests.getDummyObjectCall().execute();
DummyObject dummyObject = response.body();// Async (non blocking)
ApiRequests
.getDummyObjectCall()
.enqueue(new Callback<DummyObject>()
{
@Override
public void onResponse(Response<DummyObject> response)
{
// Deal with the response here
DummyObject dummyObject = response.body();
}

@Override
public void onFailure(Throwable t)
{
// Deal with the error here
}
});

You have to realize we have a wrapper (Response<T>), which contains our parsed object. Just call the body() method to get it.

Picasso set up

Picasso doesn’t need any setup. If you have OkHttp in your project, Retrofit will use it automatically, it’s not necessary but recommended. Just drop the dependency in and you are ready to go.

Picasso
.with(context)
.load(imageUrl)
.placeholder(R.drawable.ic_sun_smile)
.error(R.drawable.ic_cloud_sad)
.into(mImageView);
Loading image in Picasso is a “one liner”

Opinionated and focused

Small, focused and opinionated libraries are my way to go. Having a specific goal with limited scope helps in different ways: Small method count, light in size and trying to solve that problem better than any other piece of code out there. It is much more clear to know if that’s the library I’m looking for and it’s more likely that works like a pluggable component in my project, which makes it easy to replace in the future in case my needs change.

Using libraries with tons of features means most of users will be using a small percentage of those features, understanding less percentage of the code (which means difficulties while troubleshooting or customizing), adding a lot of methods to the method count and more weight to the APK. It’s more difficult to understand which problems the library solves and it is likely that the library is very good at doing something, but is not as good doing a different thing that I’ll end up using another library for (having two libraries in the project that try to solve the same problem).

Okio, OkHttp, Retrofit, Moshi and Picasso are small, opinionated and focused. This approach is one of the nicest features they have and one of the reasons behind their success.

Interesting facts

  • OkHttp engine is backing HttpURLConnection as of Android 4.4. Twitter, Facebook and Snapchat bundle it as well.
  • Retrofit 2.0 depends on OkHttp, which depends on Okio. This wasn’t the case before version 2.0.
  • All of the libraries mentioned here are developed by the Square guys.

Final thoughts

  • Very simple APIs
  • Plug and play components.
  • Actively in development.
  • They work incredibly well together as a consequence of the fact they are been developed by the same team.

Resources

Code sample

Android Developer