Retrofit API Tutorial in Android

Retrofit API Tutorial in Android with Example (Java) 2026

Retrofit API Tutorial in Android

Retrofit is a type-safe HTTP client for Android and Java, built by Square. It makes it easy to consume JSON or XML data and parse it into Plain Old Java Objects (POJOs).

Retrofit simplifies retrieving and uploading JSON (or other structured data) through a REST-based web service. You configure which converter is used for data serialization, and Retrofit internally uses the OkHttp library for HTTP requests.

Retrofit Flow Diagram

Retrofit architecture flow showing request, converter and response
Retrofit request and response flow in Android.

Output Screen

Android app output screen showing user list loaded using Retrofit
Users loaded from REST API using Retrofit and displayed in a RecyclerView.

Step 1: Add Retrofit Dependencies in Gradle

implementation 'com.google.android.material:material:1.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

Step 2: Create Model Classes

Geo.java

package com.example.helloworld;

import com.google.gson.annotations.SerializedName;

public class Geo {
    @SerializedName("lat")
    private String lat;
    @SerializedName("lng")
    private String lng;

    public Geo(String lat, String lng) {
        this.lat = lat;
        this.lng = lng;
    }

    public String getLat() {
        return lat;
    }

    public void setLat(String lat) {
        this.lat = lat;
    }

    public String getLng() {
        return lng;
    }

    public void setLng(String lng) {
        this.lng = lng;
    }
}

Address.java

package com.example.helloworld;

import com.google.gson.annotations.SerializedName;

public class Address {
    @SerializedName("street")
    private String street;
    @SerializedName("suite")
    private String suite;
    @SerializedName("city")
    private String city;
    @SerializedName("zipcode")
    private String zipcode;
    @SerializedName("geo")
    private Geo geo;

    public Address(String street, String suite, String city, String zipcode, Geo geo) {
        this.street = street;
        this.suite = suite;
        this.city = city;
        this.zipcode = zipcode;
        this.geo = geo;
    }

    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }

    public String getSuite() { return suite; }
    public void setSuite(String suite) { this.suite = suite; }

    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }

    public String getZipcode() { return zipcode; }
    public void setZipcode(String zipcode) { this.zipcode = zipcode; }

    public Geo getGeo() { return geo; }
    public void setGeo(Geo geo) { this.geo = geo; }
}

Company.java

package com.example.helloworld;

import com.google.gson.annotations.SerializedName;

public class Company {
    @SerializedName("name")
    private String name;
    @SerializedName("catchPhrase")
    private String catchPhrase;
    @SerializedName("bs")
    private String bs;

    public Company(String name, String catchPhrase, String bs) {
        this.name = name;
        this.catchPhrase = catchPhrase;
        this.bs = bs;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getCatchPhrase() { return catchPhrase; }
    public void setCatchPhrase(String catchPhrase) { this.catchPhrase = catchPhrase; }

    public String getBs() { return bs; }
    public void setBs(String bs) { this.bs = bs; }
}

User.java

package com.example.helloworld;

import com.google.gson.annotations.SerializedName;

public class User {
    @SerializedName("id")
    private int id;
    @SerializedName("name")
    private String name;
    @SerializedName("username")
    private String username;
    @SerializedName("email")
    private String email;
    @SerializedName("phone")
    private String phone;
    @SerializedName("website")
    private String website;
    @SerializedName("company")
    private Company company;
    @SerializedName("address")
    private Address address;

    public User(int id, String name, String username, String email,
                String phone, String website, Company company, Address address) {
        this.id = id;
        this.name = name;
        this.username = username;
        this.email = email;
        this.phone = phone;
        this.website = website;
        this.company = company;
        this.address = address;
    }

    public Company getCompany() { return company; }
    public void setCompany(Company company) { this.company = company; }

    public Address getAddress() { return address; }
    public void setAddress(Address address) { this.address = address; }

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

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }

    public String getWebsite() { return website; }
    public void setWebsite(String website) { this.website = website; }
}

Step 3: Create Retrofit Singleton Class

SingleTask.java

package com.example.helloworld;

import android.app.Application;

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

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

    @Override
    public void onCreate() {
        super.onCreate();
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
    }

    public Retrofit getRetrofit() {
        return retrofit;
    }
}

Step 4: Define API Interface

UserOperation.java

package com.example.helloworld;

import java.util.List;

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

public interface UserOperation {

    @GET("/users")
    Call<List<User>> getAllUsers();
}

Step 5: Load Data in MainActivity

MainActivity.java

package com.example.helloworld;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Toast;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;

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

        initViews();

        SingleTask singleTask = (SingleTask) getApplication();
        UserOperation userOperation = singleTask.getRetrofit().create(UserOperation.class);

        Call<List<User>> mycall = userOperation.getAllUsers();
        mycall.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                if (response.body() != null) {
                    getUserData(response.body());
                }
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
                Toast.makeText(MainActivity.this, "There is some problem", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initViews() {
        recyclerView = findViewById(R.id.myrec);
    }

    private void getUserData(List<User> userList) {
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        CustomUserAdapter customUserAdapter = new CustomUserAdapter(userList);
        recyclerView.setAdapter(customUserAdapter);
    }
}

Step 6: Create RecyclerView Adapter

CustomUserAdapter.java

package com.example.helloworld;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class CustomUserAdapter extends RecyclerView.Adapter<CustomUserAdapter.MyView> {

    private List<User> userList;

    public CustomUserAdapter(List<User> userList) {
        this.userList = userList;
    }

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

    @Override
    public void onBindViewHolder(@NonNull MyView holder, int position) {
        User user = userList.get(position);
        holder.tname.setText(user.getName());
        holder.temail.setText(user.getEmail());
        holder.tcompany.setText(user.getCompany().getName());
        holder.twebsite.setText(user.getWebsite());
    }

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

    class MyView extends RecyclerView.ViewHolder {
        private TextView tcompany, tname, twebsite, temail;

        public MyView(@NonNull View itemView) {
            super(itemView);
            tcompany = itemView.findViewById(R.id.company);
            tname = itemView.findViewById(R.id.name);
            twebsite = itemView.findViewById(R.id.website);
            temail = itemView.findViewById(R.id.email);
        }
    }
}

Step 7: Layout Files

res/layout/activity_main.xml

<?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:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/myrec"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

res/layout/item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardMaxElevation="10dp"
    app:cardUseCompatPadding="true">

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="1">

        <TableRow>
            <TextView android:text="Name : " android:textStyle="bold" />
            <TextView android:id="@+id/name" />
        </TableRow>

        <TableRow>
            <TextView android:text="Email : " android:textStyle="bold" />
            <TextView android:id="@+id/email" />
        </TableRow>

        <TableRow>
            <TextView android:text="Company : " android:textStyle="bold" />
            <TextView android:id="@+id/company" />
        </TableRow>

        <TableRow>
            <TextView android:text="Website : " android:textStyle="bold" />
            <TextView android:id="@+id/website" />
        </TableRow>

    </TableLayout>

</androidx.cardview.widget.CardView>

Step 8: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:name=".SingleTask"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

Frequently Asked Questions

What is Retrofit in Android?

Retrofit is a type-safe HTTP client for Android and Java built by Square. It converts REST API responses into Java objects using converters such as Gson, and internally uses OkHttp for HTTP requests.

How do I add Retrofit to an Android project?

Add the Retrofit and Gson converter dependencies in build.gradle: com.squareup.retrofit2:retrofit and com.squareup.retrofit2:converter-gson. Also add the INTERNET permission in AndroidManifest.xml.

Why should Retrofit be a singleton?

Retrofit instances are expensive to create because they hold OkHttp clients, converters, and thread pools. Using a singleton avoids creating multiple instances and improves performance.

What does @SerializedName do in Gson?

@SerializedName maps a JSON field name to a Java field. It is useful when the JSON key differs from the Java field name or when using naming conventions that differ from the API.

Can I use Retrofit with Kotlin?

Yes. Retrofit works with both Java and Kotlin. In Kotlin, you can use suspend functions with Retrofit 2.6.0 or later, or use coroutines with a CallAdapter.

Conclusion

In this Retrofit API tutorial for Android, you learned how to add Retrofit dependencies, create Gson model classes, define an API interface, build a Retrofit singleton, and display JSON data in a RecyclerView using a custom adapter.

Related topics: Android Retrofit Tutorial, Gson JSON Parsing, OkHttp Android, RecyclerView Adapter, Android REST API, Retrofit Singleton Pattern

No comments: