Retrofit 2 CRUD Android Example - CRUD REST API using Retrofit 2 in Android Studio

Overview

In this tutorial We will show you how to create a simple Android application for User CREATE, READ, UPDATE, DELETE with Android Studio. This app will send the CRUD requests to the RESTFul Web Service using Retrofit 2 HTTP Client.
Follow the steps mentioned below to develop this application.

Retrofit 2 CRUD Android Example

Video Tutorial


Project Structure



project structure

Review CRUD RESTFul Webservices

The following images show the creation of CRUD API using RESTFul Webservices call in Postman.
Hostname: localhost(My LAN IP Address: 169.254.35.189)
GET All User API
Request Method: GET
URL: http://169.254.35.189:8080/demo/user/
get user api
POST Add User API
Request Method: POST
URL: http://169.254.35.189:8080/demo/add/
add user api
PUT Update User API
Request Method: PUT
URL: http://169.254.35.189:8080/demo/update/3
update user api
DELETE User API
Request Method: DELETE
URL: http://169.254.35.189:8080/demo/delete/3
delete user api

Create Android Project with Android Studio

Open Android Studio create a new project with an empty activity called MainActivity. Find the steps to create the Android Project.

create new project
MainActivity

Add Gradle dependencies and permission


Add the following dependencies to your build.gradle file.
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.google.code.gson:gson:2.6.1'
build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.jackrutorial.androidretrofit2crud"
        minSdkVersion 21
        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.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.google.code.gson:gson:2.6.1'
}
Add the permission to access internet in the AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET" />
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.jackrutorial.androidretrofit2crud">

    <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=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".UserActivity"
            android:parentActivityName=".MainActivity"
            >
            <!-- Parent activity meta-data to support 4.0 and lower -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
    </application>

</manifest>

User Model

Create a new package to src/main/java with the name com.jackrutorial.androidretrofit2crud.model.
Create a User class under com.jackrutorial.androidretrofit2crud.model package and write the following code in it.
package com.jackrutorial.androidretrofit2crud.model;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class User {
    @SerializedName("id")
    @Expose
    private int id;

    @SerializedName("name")
    @Expose
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    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;
    }
}

Retrofit Interface

UserService 

Create a new package to src/main/java with the name com.jackrutorial.androidretrofit2crud.remote.
Create a UserService interface under com.jackrutorial.androidretrofit2crud.remote package. In this interface, we'll define GET, POST, PUT, DELETE method that perform HTTP requests with @GET, @POST, @PUT, @DELETE annotations and write the following code in it.
package com.jackrutorial.androidretrofit2crud.remote;


import com.jackrutorial.androidretrofit2crud.model.User;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;

public interface UserService {

    @GET("user/")
    Call<List<User>> getUsers();

    @POST("add/")
    Call<User> addUser(@Body User user);

    @PUT("update/{id}")
    Call<User> updateUser(@Path("id") int id, @Body User user);

    @DELETE("delete/{id}")
    Call<User> deleteUser(@Path("id") int id);
}

RetrofitClient 

Create a RetrofitClient class under com.jackrutorial.androidretrofit2crud.remote package and write the following code in it.
package com.jackrutorial.androidretrofit2crud.remote;

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

public class RetrofitClient {

    private static Retrofit retrofit = null;

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

        return retrofit;
    }

}

APIUtils

Create a ApiUtils class under com.jackrutorial.androidretrofit2crud.remote package and write the following code in it.
package com.jackrutorial.androidretrofit2crud.remote;

public class APIUtils {

    private APIUtils(){
    };

    public static final String API_URL = "http://169.254.35.189:8080/demo/";

    public static UserService getUserService(){
        return RetrofitClient.getClient(API_URL).create(UserService.class);
    }

}

Adjust activity

Change the activity_main.xml layout to the following.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.jackrutorial.androidretrofit2crud.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <Button
            android:id="@+id/btnAddUser"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Add User"
            android:background="#BA55D3"
            android:textColor="#ffffff"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            />

        <Button
            android:id="@+id/btnGetUsersList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Fetch users"
            android:background="#32CD32"
            android:textColor="#ffffff"
            android:layout_marginBottom="5dp"
            />

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </ListView>


    </LinearLayout>

</android.support.constraint.ConstraintLayout>
Change MainActivity activity code to the following.
package com.jackrutorial.androidretrofit2crud;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import com.jackrutorial.androidretrofit2crud.model.User;
import com.jackrutorial.androidretrofit2crud.remote.APIUtils;
import com.jackrutorial.androidretrofit2crud.remote.UserService;

import java.util.ArrayList;
import java.util.List;

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

public class MainActivity extends AppCompatActivity {

    Button btnAddUser;
    Button btnGetUsersList;
    ListView listView;

    UserService userService;
    List<User> list = new ArrayList<User>();

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

        setTitle("Retrofit 2 CRUD Demo");

        btnAddUser = (Button) findViewById(R.id.btnAddUser);
        btnGetUsersList = (Button) findViewById(R.id.btnGetUsersList);
        listView = (ListView) findViewById(R.id.listView);
        userService = APIUtils.getUserService();

        btnGetUsersList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //get users list
                getUsersList();
            }
        });

        btnAddUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, UserActivity.class);
                intent.putExtra("user_name", "");
                startActivity(intent);
            }
        });
    }

    public void getUsersList(){
        Call<List<User>> call = userService.getUsers();
        call.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                if(response.isSuccessful()){
                    list = response.body();
                    listView.setAdapter(new UserAdapter(MainActivity.this, R.layout.list_user, list));
                }
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
            }
        });
    }
}

Create User Activity

  • Right Click the app folder choose File > New > Activity > Empty Activity
  • Name the new activity "UserActivity".
  • Click Finish.
Change the activity_user.xml layout to the following.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.jackrutorial.androidretrofit2crud.UserActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:id="@+id/txtUId"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="ID"
            android:textSize="20dp"
            android:layout_marginTop="5dp"
            />

        <EditText
            android:id="@+id/edtUId"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="number"
            />

        <TextView
            android:id="@+id/txtUUsername"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="USER NAME"
            android:textSize="20dp"
            android:layout_marginTop="5dp"
            />

        <EditText
            android:id="@+id/edtUsername"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

        <Button
            android:id="@+id/btnSave"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Save"
            android:background="#32CD32"
            android:textColor="#ffffff"
            android:layout_marginBottom="5dp"
            />

        <Button
            android:id="@+id/btnDel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Delete User"
            android:background="#FF0000"
            android:textColor="#ffffff"
            />

    </LinearLayout>

</android.support.constraint.ConstraintLayout>
Change UserActivity activity code to the following.
package com.jackrutorial.androidretrofit2crud;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.jackrutorial.androidretrofit2crud.model.User;
import com.jackrutorial.androidretrofit2crud.remote.APIUtils;
import com.jackrutorial.androidretrofit2crud.remote.UserService;

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

public class UserActivity extends AppCompatActivity {

    UserService userService;
    EditText edtUId;
    EditText edtUsername;
    Button btnSave;
    Button btnDel;
    TextView txtUId;

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

        setTitle("Users");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        txtUId = (TextView) findViewById(R.id.txtUId);
        edtUId = (EditText) findViewById(R.id.edtUId);
        edtUsername = (EditText) findViewById(R.id.edtUsername);
        btnSave = (Button) findViewById(R.id.btnSave);
        btnDel = (Button) findViewById(R.id.btnDel);

        userService = APIUtils.getUserService();

        Bundle extras = getIntent().getExtras();
        final String userId = extras.getString("user_id");
        String userName = extras.getString("user_name");

        edtUId.setText(userId);
        edtUsername.setText(userName);

        if(userId != null && userId.trim().length() > 0 ){
            edtUId.setFocusable(false);
        } else {
            txtUId.setVisibility(View.INVISIBLE);
            edtUId.setVisibility(View.INVISIBLE);
            btnDel.setVisibility(View.INVISIBLE);
        }

        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                User u = new User();
                u.setName(edtUsername.getText().toString());
                if(userId != null && userId.trim().length() > 0){
                    //update user
                    updateUser(Integer.parseInt(userId), u);
                } else {
                    //add user
                    addUser(u);
                }
            }
        });

        btnDel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                deleteUser(Integer.parseInt(userId));

                Intent intent = new Intent(UserActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });

    }

    public void addUser(User u){
        Call<User> call = userService.addUser(u);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if(response.isSuccessful()){
                    Toast.makeText(UserActivity.this, "User created successfully!", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
            }
        });
    }

    public void updateUser(int id, User u){
        Call<User> call = userService.updateUser(id, u);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if(response.isSuccessful()){
                    Toast.makeText(UserActivity.this, "User updated successfully!", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
            }
        });
    }

    public void deleteUser(int id){
        Call<User> call = userService.deleteUser(id);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if(response.isSuccessful()){
                    Toast.makeText(UserActivity.this, "User deleted successfully!", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Create User Adapter


Create a UserAdapter class under com.jackrutorial.androidretrofit2crud package and write the following code in it.
package com.jackrutorial.androidretrofit2crud;

import android.content.Context;
import android.content.Intent;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.jackrutorial.androidretrofit2crud.model.User;

import java.util.List;

public class UserAdapter extends ArrayAdapter<User> {

    private Context context;
    private List<User> users;

    public UserAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<User> objects) {
        super(context, resource, objects);
        this.context = context;
        this.users = objects;
    }

    @Override
    public View getView(final int pos, View convertView, ViewGroup parent){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.list_user, parent, false);

        TextView txtUserId = (TextView) rowView.findViewById(R.id.txtUserId);
        TextView txtUsername = (TextView) rowView.findViewById(R.id.txtUsername);

        txtUserId.setText(String.format("#ID: %d", users.get(pos).getId()));
        txtUsername.setText(String.format("USER NAME: %s", users.get(pos).getName()));

        rowView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //start Activity User Form
                Intent intent = new Intent(context, UserActivity.class);
                intent.putExtra("user_id", String.valueOf(users.get(pos).getId()));
                intent.putExtra("user_name", users.get(pos).getName());
                context.startActivity(intent);
            }
        });

        return rowView;
    }
}
Create the list_user.xml file under res/layout/ folder to the following.
Click on app > res > layout > Right Click on layout. Select New > XML > Layout XML File. In the dialog that appears, enter list_user as name for the file. Then change the list_user.xml layout to the following.
<?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"
    >

    <TextView
        android:id="@+id/txtUserId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="3dp"
        />

    <TextView
        android:id="@+id/txtUsername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="3dp"
        />

</LinearLayout>

Run this application with the Android Emulator

You can run this app from an Android Studio project. Or you can run this app that's been installed on the emulator as you would run any app on a device. To start the emulator and run this app in your project.
  • Open Android Studio project and click Run.
  • In the Select Deployment Target dialog, select an existing emulator definition, and then click OK.
Note
  • If you don’t see a definition you want to use, click Create New Virtual Device to launch the AVD Manager. After you define a new AVD, in the Select Deployment Target dialog, click OK.
  • If you want to use this emulator definition as the default for your project, select Use same selection for future launches.
Run this application with the Android Emulator
Run this application with the Android Emulator
Run this application with the Android Emulator
Run this application with the Android Emulator
Run this application with the Android Emulator
Retrofit 2 CRUD Android Example
Fetch Users Screen
Retrofit 2 CRUD Android Example
Add User Screen
Retrofit 2 CRUD Android Example
Update and Delete User Screen

References

Previous Post
Next Post

post written by: