Now you can Subscribe using RSS

Submit your Email

Thursday

Android Retrofit JSON API with POST-GET Params Tutorial | Example App

Vishal Shrestha

Welcome fellow Android Developer, in the Retrofit tutorial I will give you an Android example of how you can integrate Retrofit to handle JSON response from a REST API in your Android app.
We will go over the following things in this Retrofit tutorial:
Retrofit
1. Retrofit and Gson Dependencies for Android
2. Setting us Retrofit Client and Interface
3. Create model class for Gson Parsing
4. Creating XML Layout
5. Creating RecyclerView Adapter
6. Creating MainActivity to make Retrofit JSON API calls.
 
Retrofit Android Example
Retrofit is a library for Android developed by Square to perform and handle REST API call in our Android application. Retrofit make it very easy to handle JSON response (or any other structured response) from REST API calls. In this tutorial, our example app will use Gson as converter to directly convert JSON response from our POST/GET calls to model objects. If required, we can add custom converters to Retrofit.
In this Example, we will use jservice API as you don't need any key for that, and it returns JSON response. You can check it out here: JService.
Here's the JSON response that is returned.
Jservice-JSON-Response
Json Response from Jservice API


Using Retrofit in Android App
To use Retrofit, first of all you need to add some dependencies to you app level Gradle file. Add the following dependencies to your Android app:

    //Retrofit, gson
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'

    compile 'com.squareup.retrofit2:retrofit:2.0.2'

    // recycler view
    compile 'com.android.support:recyclerview-v7:26.1.0'


The first two dependency are for Gson converter, we will use Gson as the converter for the response to our Retrofit API calls. The third dependency is for the Retrofit Library itself. The fourth dependency is for RecyclerView as we will display the result from API calls in a RecyclerView. Now we have the necessary APIs for our example app. Let's move to the next section of Retrofit integration in Android app.

Retrofit ApiClient and Retrofit Interface setup
It is recommended that we use a single instance of Retrofit throughout our whole application. So we need a static Retrofit variable. So create a new package, name it network and create a new Java Class inside it. Name the class ApiClient. Here's the code inside ApiClient class:

public class ApiClient {
    public static final String BASE_URL = "http://jservice.io/api/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit == null)
            retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();

        return retrofit;
    }
}


Now we need to create an Interface consisting of methods that will have methods for our required API calls. Create a new class inside network package. Name it ApiInterface. Here's the code in ApiInterface:

public interface ApiInterface {
    @GET("random")
    Call<List<QuestionModel>> getRandomQuestions(@Query("count") int count);

    /*
    @FormUrlEncoded
    @POST("login")
    Call<UserInfo> doLogin(@Field("username") String uname, @Field("pwd") String pwd);
    */
}

The @GET annotation is used for get methods,the @Query is used as the parameter name, and then we pass the parameter value after that, i.e int count in the example above. If we call the getRandomQuestions above, it will call an API like: http://jservice.io/api/random/?count=(AnyValueWePassWhileCallingTheAPI). It will return a list of QuestionModel, but now we don't have a question model, so it will be showing error. We will create the models in the next step.
For POST API calls, we can send parameter using the @Field annotation as shown in the code above, the value in @Field annotation is the parameter name and the value is passed after that.
Retrofit provides a number of other options of parameters that we can pass to a method, they are:
    @Body – Sends Java objects as request body.
    @Url – uses dynamic URLs.
    @Header - Sends header values.
      
 Our Retrofit Network classes are done, now let's create the question models.

Create Model Classes for JSON Parsing
Create a new package, name it models. Inside models create a new Java class called CategoryModel, here's the code:

class CategoryModel {
    @SerializedName("id")
    int id;
    @SerializedName("title")
    String title;
    @SerializedName("created_at")
    String created_at;
    @SerializedName("updated_at")
    String updated_at;
    @SerializedName("clues_count")
    int clues_count;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

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

    public String getCreated_at() {
        return created_at;
    }

    public void setCreated_at(String created_at) {
        this.created_at = created_at;
    }

    public String getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }

    public int getClues_count() {
        return clues_count;
    }

    public void setClues_count(int clues_count) {
        this.clues_count = clues_count;
    }
} 

Now lets create a class for the actual Question that we will get, create a new class inside models folder, name it QuestionModel. Here the code:
public class QuestionModel {
    @SerializedName("id")
    int id;
    @SerializedName("answer")
    String answer;
    @SerializedName("question")
    String question;
    @SerializedName("value")
    int value;
    @SerializedName("airdate")
    String airdate;
    @SerializedName("created_at")
    String created_at;
    @SerializedName("updated_at")
    String updated_at;
    @SerializedName("category")
    CategoryModel category;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public String getAirdate() {
        return airdate;
    }

    public void setAirdate(String airdate) {
        this.airdate = airdate;
    }

    public String getCreated_at() {
        return created_at;
    }

    public void setCreated_at(String created_at) {
        this.created_at = created_at;
    }

    public String getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }

    public CategoryModel getCategory() {
        return category;
    }

    public void setCategory(CategoryModel category) {
        this.category = category;
    }
}

Notice that I have not create variables for all the returned data, as I will not be using most of that. You can just create variables for parameters that you are interested from the JSON Response. Also, it's very important to add the @SerializedName annotation as that's used for automatic parsing.

Now since we have everything ready, we just need to call the getQuestions Method and display the data.

Creating the Layout for Retrofit App
Create a new layout resource for the  android app, call in activity_main.xml. Here's the code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

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

This is pretty simple layout, it just has a RecyclerView that will be used to Display the data that we will get from the API.
Now we will create a layout for individual row of the RecyclerView. Create a layout, name it question_row. Here's the code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="8dp">

    <TextView
        android:id="@+id/tvQuestion"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Question"
        android:textSize="22sp" />

    <TextView
        android:id="@+id/tvPoints"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:text="200" />
</LinearLayout>


Now let's create an adapter for the RecyclerView to display the data.

Creating RecyclerView Adapter and ViewHolder
Create a new class called QuestionsAdapter, this will be the adapter for our RecyclerView. If you want to know more about RecyclerView, check out this tutorial: RecyclerView.
Here's the code inside QuestionsAdapter:

public class QuestionsAdapter extends RecyclerView.Adapter<QuestionsAdapter.QuestionsHolder> {
    ArrayList<QuestionModel> questionModels;

    public QuestionsAdapter(ArrayList<QuestionModel> questionModels) {
        this.questionModels = questionModels;
    }

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

    @Override
    public void onBindViewHolder(QuestionsHolder holder, int position) {
        holder.question.setText(questionModels.get(position).getQuestion());
        holder.points.setText(questionModels.get(position).getValue() + "");
    }

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

    public class QuestionsHolder extends RecyclerView.ViewHolder {
        TextView question, points;

        public QuestionsHolder(View itemView) {
            super(itemView);
            question = itemView.findViewById(R.id.tvQuestion);
            points = itemView.findViewById(R.id.tvPoints);
        }
    }
}
 

Now everything is ready, we just need a main activity to call the Retrofit GET method and  display the data in RecyclerView.

Creating MainActivity and Calling Retrofit GET method.
Create a new activity, call it MainActivity. We will call the user the ApiClient that we had created earlier to get a Retrofit instance and then call the GET method to get the details and set the adapter to our RecyclerView and we our done with our Android app with Retrofit API Calls. Here's the code in MainActivity.java:

public class MainActivity extends AppCompatActivity {

    RecyclerView rvQuestions;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rvQuestions = findViewById(R.id.rvQuestions);
        setQuestions();
    }

    private void setQuestions() {
        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
        Call<List<QuestionModel>> call = apiInterface.getRandomQuestions(5);
        call.enqueue(new Callback<List<QuestionModel>>() {
            @Override
            public void onResponse(Call<List<QuestionModel>> call, Response<List<QuestionModel>> response) {
                int status = response.code();
                ArrayList<QuestionModel> questionModels = (ArrayList<QuestionModel>) response.body();
                setRecyclerView(questionModels);
            }

            @Override
            public void onFailure(Call<List<QuestionModel>> call, Throwable t) {

            }
        });
    }

    private void setRecyclerView(ArrayList<QuestionModel> questionModels) {
        rvQuestions.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        QuestionsAdapter questionsAdapter = new QuestionsAdapter(questionModels);
        rvQuestions.setAdapter(questionsAdapter);
    }
}

 

We are almost done, here's our final project structure:

retrofit-android-json-post-api-example
Retrofit Android Example App
Now we just need to edit the manifest and add our Activity as launcherActivity and add internet access permission to allow Retrofit API calls, here's the manifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thecodecity.retrofitjsondemo">

    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".models.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


We can now run our App, here's a screenshot:
JSON-response-from-API-call-Android-App
Android App Retrofit Example


We learned how we can integrate Retrofit in our Android app and make GET and POST calls, get JSON Response, Parse it automatically using Gson converter. Retrofit is very helpful and I highly recommend it. Hope this tutorial helped you! Cheers. If you have any questions, feel free to drop them below, I be happy to help.

Vishal Shrestha / Author & Founder

A developer by profession, a born Adventurer. I mainly do Android but like to get my hands dirty with web development and a little bit of Python. I would't rather go on a Trek than a party and you can find me having a few rounds with the heavy bag to let out the steam ;)

WORK

Research and Development at : Ekghanti

Mobile Technology Lead at : Vimvox Lab

For Business info : My Portfolio Site

0 comments:

Post a Comment

Coprights @ 2017 | The Code City by Vishal Shrestha Vishal Shrestha