Android Retrofit 2 with JSON API Example

Retrofit is a type-safe REST client for Android built by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.

Retrofit makes downloading JSON or XML data from a web API fairly straightforward. Once the data is downloaded then it is parsed into a Plain Old Java Object (POJO) which must be defined for each “resource” in the response.

Retrofit turns your HTTP API into a Java interface.

In this tutorial, we are going to learn how you can use retrofit 2 in your android application to consume a restful / Json API.

We are not going to build our own Json API rather we will make use of free available Json API in the web.

There are many websites that offer this for free. I am going to use www.mocky.io. You can visit the website and created your own Json response output.

We will create an array of objects. Each object will contain a title and description attributes. This is so simple but if you want something different you can go ahead and do it.

Using the service can be handy especially when you want to quickly test certain Json response object in your android application.

Go to mocky.io and place the code below in the body field.

[
{
"id": 1,
"title": "This is the first title",
"description": "The first post is what we used to test the system and see if it is working"
},
{
"id": 2,
"title": "This is the second post",
"description": "We have little to talk about the second post"
},
{
"id": 3,
"title": "This is the third post",
"description": "The third post is amazing and very refreshing"
}
]

Click on generate my http response button to get a link that look like below.

http://www.mocky.io/v2/5a96abc232000057005e2ed3940

Before we proceed to create new android application, the screenshot below will show you want we will code in this tutorial.

Note that the knowledge you will gain can be implement in different mobile app that requires network call.

Android retrofit

Create new android project

Lets start to soil our hands in code. Start up your IDE. For this tutorial, I am using the following tools and environment, feel free to use what works for you.

Windows 10

Android Studio

Sony Xperia H1313

Min SDK 16

Target SDK 26

To create a new android application project, follow the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidRetrofit2

Package: com.inducesmile.androidRetrofit2

Select Empty Activity

Name your activity: MainActivity

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

Add library dependencies in build.gradle

In order to use Retrofit 2 in our android application, we will first install the library which will give us access to all the classes and methods the library exposes

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.google.code.gson:gson:2.8.0'

The Gson library is used for Java object serialization and deserialization.

There are other libraries we will also add that will provide new functionalities and view components for us.

Below is how our project build.gradle will look like.

apply plugin: 'com.android.application'
android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.inducesmile.retrofit2"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:cardview-v7:26.1.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.google.code.gson:gson:2.8.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

String.xml

We are going to update our project strings.xml file located in the values folder inside the res folder. Open the file and add the code below to it.

<resources>
    <string name="app_name">Retrofit2</string>
</resources>

Color.xml

Open the colors.xml file in the same location as the strings.xml file and add the code below to the file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>

MainActivity.java

Open the MainActivity.java file and its layout file – activity_main.xml and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mcontent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="12dp"
    tools:context="com.inducesmile.retrofit2.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.v7.widget.RecyclerView>

</android.support.v7.widget.LinearLayoutCompat>

You can see that we have added a RecyclerView which will use to display the content we will download from the Json API.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.List;
import retro.ApiUtil;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private final String TAG = MainActivity.class.getSimpleName();

    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setHasFixedSize(true);

        ApiUtil.getServiceClass().getAllPost().enqueue(new Callback<List<ApiObject>>() {
            @Override
            public void onResponse(Call<List<ApiObject>> call, Response<List<ApiObject>> response) {
                if(response.isSuccessful()){
                    List<ApiObject> postList = response.body();
                    Log.d(TAG, "Returned count " + postList.size());
                    NewAdapter adapter = new NewAdapter(getApplicationContext(), postList);
                    recyclerView.setAdapter(adapter);
                }
            }

            @Override
            public void onFailure(Call<List<ApiObject>> call, Throwable t) {
                //showErrorMessage();
                Log.d(TAG, "error loading from API");
            }
        });
    }
}

You can see from the code above that we have added the retrofit code for network call but just ignore it for now. We will come back to it later.

RecyclerView adapter and viewholder

Lets create an adapter and viewholder java classes the RecyclerView component will use.

Create a new java file and name it NewsAdapter.java or any name of your choice. Open the file and add the code below.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;

public class NewAdapter extends RecyclerView.Adapter<NewsViewHolder>{

    private Context context;

    private List<ApiObject> apiObjectList;

    public NewAdapter(Context context, List<ApiObject> apiObjects){
        this.context = context;
        this.apiObjectList =  apiObjects;
    }

    @Override
    public NewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new NewsViewHolder(view);
    }

    @Override
    public void onBindViewHolder(NewsViewHolder holder, int position) {
        ApiObject apiObject = apiObjectList.get(position);
        holder.title.setText(apiObject.getTitle());
        holder.description.setText(apiObject.getDescription());
    }

    @Override
    public int getItemCount() {
        return apiObjectList.size();
    }
}

Create another java file and name it NewsViewHolder.java. Add the code below to the file.

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

public class NewsViewHolder extends RecyclerView.ViewHolder {

    public TextView title;

    public TextView description;

    public NewsViewHolder(View itemView) {
        super(itemView);
        title = (TextView) itemView.findViewById(R.id.post_title);
        description = (TextView) itemView.findViewById(R.id.post_description);
    }
}

Create a new package and name it retro

Inside this package, we are going to create all the files that  are associated with retrofit network call.

1. Create a new java file and name it RetrofitAPI.java. Add the code snippet to the file.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitAPI {

    public static Retrofit getRetrofit(String url) {
        Gson gson = new GsonBuilder().setLenient().create();

        return new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
}

We use the code above to create a retrofit instance using the builder pattern. The instance of retrofit is assigned a baseUrl with a converter factory specified. We are going to use Gson in this tutorial but note that there are many other converterFactory you can use like Jackson. The convert is used to serialize and deserialize java object.

2. Create a new java interface file and name it RetrofitInterface.java. Add the code below to the file

import com.inducesmile.retrofit2.ApiObject;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;


public interface RetrofitInterface {

    @GET("v2/5a96abc232000057005e2ed7")
    public Call<List<ApiObject>> getAllPost();

}

The interface class contain a GET method with path to our Json API. It maps the network response object to the ApiObject list.

3. We will create another java file and name it ApiUtil.java. Add this code snippet to the file.

public class ApiUtil {

    private static final String BASE_URL = "http://www.mocky.io/";

    public static RetrofitInterface getServiceClass(){
        return RetrofitAPI.getRetrofit(BASE_URL).create(RetrofitInterface.class);
    }
}

We are using a static method to return an instance of the RetrofitInterface class which will let us call the getAllPost().

4. We will create a plain java object that will map to our server response object. Create a new java file and name it ApiObject.java. Open the file and add the code below.

import com.google.gson.annotations.SerializedName;
public class ApiObject {

    @SerializedName("title")
    private String title;

    @SerializedName("description")
    private String description;

    public ApiObject(String title, String description) {
        this.title = title;
        this.description = description;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Finally, we will visit the MainActivity class again. Remember that we did not go deep into it but right now I will show you what we missed out on.

ApiUtil.getServiceClass().getAllPost().enqueue(new Callback<List<ApiObject>>() {

    @Override
    public void onResponse(Call<List<ApiObject>> call, Response<List<ApiObject>> response) {
        if(response.isSuccessful()){
            List<ApiObject> postList = response.body();
            Log.d(TAG, "Returned count " + postList.size());
            NewAdapter adapter = new NewAdapter(getApplicationContext(), postList);
            recyclerView.setAdapter(adapter);
        }
    }

    @Override
    public void onFailure(Call<List<ApiObject>> call, Throwable t) {
        //showErrorMessage();
        Log.d(TAG, "error loading from API");
    }

});

The code above is what connects to the Json API server and request the resources we are looking for.

We use the response.isSuccessful() to check if our network call is successful before we start manipulating the response object.

When we finally retrieve the response object, we pass it to the RecyclerView adapter which is then display on MainActivity class.

This brings us to the end of this tutorial. I hope with the simple example you are able to learn and understand how to use Retrofit 2 library for android.

You can get the complete source code of this tutorial on my Github account.

If you have any questions or suggestion about a tutorial to post, kindly use the comment box or contact form to get in touch with me.

Add a Comment