Open In App

Introduction to Retrofit in Android

Last Updated : 18 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Retrofit is a type-safe HTTP client for Android, developed by Square. It simplifies network operations by allowing developers to define REST API interactions using Java/Kotlin interfaces. It supports various request methods like GET, POST, PUT, DELETE, and PATCH while enabling seamless integration with JSON parsing libraries like Gson and Moshi.

Why Use Retrofit?

The advantages that Retrofit has over traditional network handling methods like HttpURLConnection and Volley are:

  1. Provides a clean and simple way to define API requests.
  2. Converts API responses directly into Java/Kotlin objects, making it type safe.
  3. Supports both asynchronous calls (using enqueue) and synchronous calls (using execute).
  4. Allows adding custom headers, logging, and authentication easily.
  5. Can be extended with converter, thus highly scalable.

Step by Step Implementation:

In this article, we will be implementing the GET request method. To know more about the other request methods refer to

Step 1: Add necessary dependencies

For using Retrofit in our Android project firstly we have to add dependency in the gradle file. For adding dependency open app/build.gradle file in your Android project and add the following lines inside it. Add these lines inside dependencies{} 

dependencies {
implementation ("com.google.code.gson:gson:2.9.1")
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
}

Step 2: Provide internet permission

We should now add Internet Permission inside Manifest file. Open the AndroidManifest.xml file and add the following line. 

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

Step 3: Create a model class for data response from API

For retrieving data from the server using retrofit 2 we require a model class. We are going to make a model class to retrieve data from the server. Set the name of the class ResponseData.

directory-structure-retrofit

ResponseData Class:

ResponseData.java
package org.geeksforgeeks.demo;

import com.google.gson.annotations.SerializedName;

public class ResponseData {
    
    @SerializedName("body")
    private String body;
    
    @SerializedName("id")
    private int id;
    
    @SerializedName("title")
    private String title;
    
    @SerializedName("userId")
    private int userId;

    public ResponseData(String body, int id, String title, int userId) {
        this.body = body;
        this.id = id;
        this.title = title;
        this.userId = userId;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    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 int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
}
ResponseData.kt
package org.geeksforgeeks.demo

data class ResponseData(
    val body: String,
    val id: Int,
    val title: String,
    val userId: Int
)


Step 4: Create a Retrofit Object/Instance

Create an retrofit instance to define API base url.

RetrofitInstance Class:

RetrofitInstance.java
package org.geeksforgeeks.demo;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitInstance {
    private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
    private static Retrofit retrofit;

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

    public static ApiInterface getApiInterface() {
        return getRetrofitInstance().create(ApiInterface.class);
    }
}
RetrofitInstance.kt
package org.geeksforgeeks.demo

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
    private val retrofit by lazy {
        Retrofit.Builder().baseUrl("https://jsonplaceholder.typicode.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    val apiInterface by lazy {
        retrofit.create(ApiInterface::class.java)
    }
}


Step 5: Create a API interface

Create an interface to define API endpoints and their request types.

ApiInterface Class:

ApiInterface.java
package org.geeksforgeeks.demo;

import retrofit2.Call;
import retrofit2.http.GET;

public interface ApiInterface {
    @GET("/posts/1")
    Call<ResponseData> getData();
}
ApiInterface.kt
package org.geeksforgeeks.demo

import retrofit2.Call
import retrofit2.http.GET

interface ApiInterface {
    @GET("/posts/1")
    fun getData(): Call<ResponseData>
}


Step 6: Working with activity_main.xml

Navigate to app > res > layout > activity_main.xml and make the below changes. We will be adding 2 textviews and a button to fetch the data.

activity_main.xml:

activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <TextView
        android:id="@+id/title_textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginEnd="32dp"
        android:text="Title"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/body_textView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />

    <TextView
        android:id="@+id/body_textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:text="Body"
        android:textSize="16sp"
        android:textStyle="italic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title_textView" />

    <Button
        android:id="@+id/getData_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Get Data"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/body_textView" />
</androidx.constraintlayout.widget.ConstraintLayout>

Design UI:

design-ui-retrofit

Step 7: Working with MainActivity file

In this file, we will call the Retrofit Instance to get the data and bind it to the view. Navigate to app > kotlin+java > {package-name} > MainActivity.java/MainActivity.kt and make the necessary changes given below.

MainActivity File:

MainActivity.java
package org.geeksforgeeks.demo;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private TextView titleTextView;
    private TextView bodyTextView;
    private Button getDataButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        titleTextView = findViewById(R.id.title_textView);
        bodyTextView = findViewById(R.id.body_textView);
        getDataButton = findViewById(R.id.getData_button);

        getDataButton.setOnClickListener(view -> getData());
    }

    private void getData() {
        ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Please wait");
        progressDialog.show();

        RetrofitInstance.getApiInterface().getData().enqueue(new Callback<ResponseData>() {
            @Override
            public void onResponse(Call<ResponseData> call, Response<ResponseData> response) {
                ResponseData responseData = response.body();
                if (responseData != null) {
                    titleTextView.setText(responseData.getTitle());
                    bodyTextView.setText(responseData.getBody());
                }
                progressDialog.dismiss();
            }

            @Override
            public void onFailure(Call<ResponseData> call, Throwable t) {
                Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
                progressDialog.dismiss();
            }
        });
    }
}
MainActivity.kt
package org.geeksforgeeks.demo

import android.app.ProgressDialog
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MainActivity : AppCompatActivity() {

    private lateinit var titleTextView: TextView
    private lateinit var bodyTextView: TextView
    private lateinit var getDataButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        titleTextView = findViewById(R.id.title_textView)
        bodyTextView = findViewById(R.id.body_textView)
        getDataButton = findViewById(R.id.getData_button)

        getDataButton.setOnClickListener {
            getData()
        }
    }

    private fun getData() {

        val progressDialog = ProgressDialog(this)
        progressDialog.setMessage("Please wait")
        progressDialog.show()

        RetrofitInstance.apiInterface.getData().enqueue(object : Callback<ResponseData?> {
            override fun onResponse(call: Call<ResponseData?>, response: Response<ResponseData?>) {
                val responseData = response.body()
                titleTextView.text = responseData?.title
                bodyTextView.text = responseData?.body
                progressDialog.dismiss()
            }

            override fun onFailure(call: Call<ResponseData?>, t: Throwable) {
                Toast.makeText(this@MainActivity, t.localizedMessage, Toast.LENGTH_SHORT).show()
                progressDialog.dismiss()
            }
        })
    }
}

Output:


Next Article

Similar Reads