This post was modified from its original version, we’ve rewritten it to include latest Retrofit 2.0+ release

I’ve recently become more and more interested in Android development and have been trying out different libraries that are supposed to be brilliant. More often than not they are really good. This is my first post in a series where I will produce a sample Android application that uses a combination of these amazing libraries so you can judge for yourself how good they are.
Today, I’ll look at using the Retrofit 2 HTTP client to see how complicated vs. how beneficial it is for my application. Retrofit is one of the amazing tools that Square Inc has released into the open source community. It’s a type-safe HTTP client, both for Android and Java applications.

The main premise behind type-safe HTTP clients is that you only need to worry about the semantics of the queries that you send over the network, rather than the details of how to construct URLs, specify parameters correctly and so forth. Retrofit makes this easy by requiring you to write just a couple of interfaces, and that’s it!

Let’s look at an example of how Retrofit2 works. The repository which I’ve added all my code to is available on Github, and as always, the best way to learn is to check it out and tinker with it yourself.

I started with an empty project in Android Studio. Personally, when welcomed with a choice of compatibility options and questions about which API I need to support in my application, I honestly get lost.

The positive thing here, of course, is that we’re just playing with a toy project, so we can boldly select the latest SDK and rush through the new project wizard to get ourselves a glorious, functioning “hello world” Android application.
Here’s the link to the commit if you don’t want to mess with the choices and rather just import the project from Github: Floating button app skeleton.

I always enable JRebel for Android for all projects. It’s packaged as an Android Studio plugin, so enabling it means that I click the custom button to run the app, everything else is taken care of. JRebel for Android is a productivity tool for Android developer that can instantly update code and resources on the running device or emulator. That essentially means that while you’re developing the application, you don’t have to waste the precious time waiting for your application to restart, often losing all the relevant application state on the way. Glorious!

So we quickly got from zero to a functional sample that we can run from the Android Studio. What is even better it’s that the new Android emulator that came with the Android Studio 2.0 is pretty snappy too. Now I see the screen with the MainActivity class active.
Clicking the floating button works and the snackbar comes up. All good, let’s verify that our infrastructure works fine by making a random code change to verify that the code reloading works. The first thing that comes to mind is to change the string value on the snackbar.

Lo and behold, one file save and one button click later we observe the updated code in action on the emulator. Now we’re unstoppable! And by that I mean we’re ready to investigate what Retrofit 2 has to offer.

Retrofit 2 is a type-safe HTTP client for Android (and Java), but first of all, it’s a library, so to use it we need to declare the correct dependencies. That is easy, however, note that we need to depend explicitly on the gson converter to transform the JSON responses to the model classes. It wasn’t the case with Retrofit 1, so be careful.

Then, given that we want our application to access the network we need to declare the INTERNET permission in the Android manifest file. This is pretty straightforward, just add this line to the app/src/main/AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />

With these preliminary tasks out of the way, we can look at the actual code. The main idea behind Retrofit is that it’s possible to generate the code to query HTTP services at runtime, requiring the developer to produce just an interface as the “specification.” Imagine we have the following model class:

This is the simplest example, we add the @GET annotation on an interface method and provide the path part of the URL that we want to expose it on. Conveniently, the method parameters can be referenced in the path string so you won’t need to jump through hoops to set those. Additionally, with other annotations you can specify query parameters, POST request body and so on:

@Query(“key”) — for GET request query parameter

@QueryMap — for the map of parameters

@Body — use it with the @POST annotation to provide the query body content.

Now, to use this interface during runtime, we’ll need to build a Retrofit object:

I like to use the Retrofit builder in the same interface that contains the queries to the website. This way I’m not tempted to complicate things beyond measure. Yeah, there’s some general configuration in use here. We provide the default converter factory to turn the JSON response objects into Java objects, but it’s better to copy-paste that into every service class you have rather than use a single abstraction only to find out it’s leaking.

With these pieces in place, we just need to perform the network call:

the specification of our queries

the Retrofit object builder

To create the implementation of the GitHubService interface, instantiate a Call object for the HTTP query which we want to perform and execute the request.

Sounds simple enough! Let’s prepare some sort of UI and wire the code in. Following the floating button app template design, we need to change the content_main.xml file. Here’s my take on adding a button to initiate the query and a text area to show the results:

Naturally, this code won’t work; the Android framework won’t allow you to perform network calls on the UI thread. The UI thread should only handle input from the user. Performing any long blocking operations on this thread will simply make the user experience sluggish.

So, we need to refactor this code by moving the network call to a background thread. With JRebel for Android, this won’t take any time at all. Let’s refactor it to use the enqueue method we looked at above.
Now the code looks like the snippet below and works too:

That’s it, the code now runs, the text view get’s updated with the result of out HTTP query.

The skeleton app is ready, the code builds and works. Now you are equipped to play with both Retrofit and JRebel for Android. You can change a line of code here and there and see the results of your new code in the running app, without any time-wasting. Try adding a couple of fields to the Contributor class. Replace the text view with a list of proper widgets for every contributor. Change the HTTP endpoint altogether and query another website. The world is your oyster.

In this post, we looked at establishing a minimal skeleton app that uses Retrofit 2 for network calls. The code is available on Github. The best way to utilize this post is to clone the app, import it into Android Studio and play with the code yourself using this post as a quick introduction to the relevant areas to focus on.

In the future, I hope I’ll expand on this skeleton app, adding a dependency injection framework to avoid messing with the UI code, throw in a bit of RxAndroid to process the network queries reactively, and so on. By the way, what are your default goto libraries, that you use in any Android project? Maybe it’ll be interesting to look at those instead. Ping me on Twitter: @shelajev, I’d be happy to chat!

Oleg Šelajev is an engineer, author, speaker, lecturer and advocate at ZeroTurnaround. He spends his time testing, coding, writing, giving conference talks, crafting blogposts and reports. He is pursuing a PhD on Dynamic System updates and code evolution. Oleg is a part-time lecturer at the University of Tartu and enjoys speaking and participating in Java/JVM development conferences such as JavaOne, JavaZone, JFokus and others. In his free time, Oleg plays chess at a semi-grandmaster level, loves puzzles and solving all kinds of problems.

The internet permission is required to run the app successfully, i think its worthwhile to mention it, seeing how this is a step by step introduction :)

I also noticed that the github code uses butterknife to bind the button view, maybe it would be worth mentioning that in this post?

Oleg Šelajev

Hi, Simon, thank you for the feedback! And I have to say both points that your raise are excellent.

The application that’ll perform network calls indeed require the INTERNET permission, I’ve added that step into the body of the post, so the readers won’t miss it.

About the butterknife for binding the views into the activity class, I need to find a good spot to mention that. However, it’s a huge and kinda tangent topic, so it might be better to avoid the confusion of describing all of it at once. I’ll think where in the text to put it and how much to dive into it.

I’m planning on writing a more detailed post on the dependency injection with Dagger and how sometimes the Butterknife is enough for all your needs. So maybe it’ll just be the new full post and a link from this one.

SaddamAkbar

hello OLEG SHELAJEV, this a super tutorial, this really really help me, i want to ask, this my json…

then the response.body will be of the List type.
List body = response.body();
So you don’t need to call body.getPosts().getTitle(), just do something like:
response.body().iterator().next().getTitle(), or iterate the body() result.

I’m not sure what do you mean if this can make the recyclerview dynamically, so unfortunately, I cannot help you with that.

Neel prajapati

hello olge which annonation i have to used In GET method for forgot password??

Adam Gardner

How would you parse something that is like? The nested arrays and all that is really confusing.

I keep getting the JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

I have made my callback for retrofit a List and same in the onResponse but still keep gettign the error.

jsajan

how to implement the POST method in your code. can you please show an example on how call the POST?

Neon Warge

login is always null for me. I don’t know why. Any idea?

I checked the Github API v3 and it states there that the URI is correct. We are targeting `repos/owner/repo/contributors`. But login is always assigned null.

Thanks!

Neon Warge

Oh crap, its because I name my login variable as mLogin. I should name my variables the same with what is indicated from the docs, hence `login`, `html_url`

Muhammad Salma Nabila Alibasyi

hi Oleg Shelajev, nice tutorial for this !
I wanna ask, how to post / show marker polyline map using json encode from mysql database? I have latitude & longitude each ID in json encode but i don’t know to code it