Android Jetpack

Working with Room Persistence Library

Pinterest LinkedIn Tumblr

What is Room Persistence Library? how is provide an abstraction layer over SQLite to allow for more robust database access? In this article, I’m going to explain how to deal with Room Persistence Library in Android.

What is Room Persistence Library?

Google has introduced is a new Library for dealing database. It is a part of android architecture components that provide an abstraction layer over the SQLite to allow for robust database access the full power of SQLite. This library helps you to create a cache of your app’s data on the local device. This cache, which serves as your app’s single source of the key information within the app. whether users have or not an internet connection.

working with room persistence library

All methods, variable,s and parameters are imported using android annotations. The following annotations are most frequently used in android room library

  • @Entity – Use to create an SQLite table in the database using the data model class
  • @Dao – Use to create a Data Access Object in the database
  • @Database – A class with this annotations will create an abstraction layer for the DAO(Data Access Object ).
  • @PrimaryKey – This annotation will set a primary key for the table.
  • @Insert – Use for Insert entity object into the table
  • @Update – Update entity object in the table
  • @Delete – Delete entity object in the table
  • @Query – Running SQL query method in the table
  • @Ignore – Ignore parameter from the room database

Let’s understand the working of Room Persistence Library with above annotation using with demo app.

Create a New Project

Open Android Studio and go to file menu, create a new project and fill detail and select EmptyActivity template and Finish.

Add Dependencies

Open the buid.gradle and room persistence dependencies, Here is annotation processor is needed for all operations like Insert, Delete, Update.

    // Room
    implementation 'android.arch.persistence.room:runtime:1.1.1'
    annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'

Add more dependencies for this build this sample app and compileOptions VERSION_1_8 because we are going to use androidx lib. so full build.gradle look like below.

apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.wave.sample"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    // Room
    implementation 'android.arch.persistence.room:runtime:1.1.1'
    annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    // ButterKnife
    implementation 'com.jakewharton:butterknife:10.0.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
Create a class with name DateConverter

Furthermore go head to creating database and entity class we have to create a DateConverter utility that convert Date to timestamp while inserting and convert timestamp to Date object while fetch data from database. So let’s create a utility class.

package com.wave.sample.utils;
import java.util.Date;
import androidx.room.TypeConverter;
/**
 * Created on : Jan 29, 2019
 * Author     : AndroidWave
 */
public class DateConverter {
    @TypeConverter
    public static Date fromTimestamp(Long value) {
        return value == null ? null : new Date(value);
    }
    @TypeConverter
    public static Long dateToTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}

Create a Table in Database

Create a java class with getter setter and denoted it with @Entity annotations. On Database instance create table will created in database.

package com.wave.sample.db.model;
import com.wave.sample.utils.DateConverter;
import java.util.Date;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
/**
 * Created on : Feb 01, 2019
 * Author     : AndroidWave
 */
@Entity(tableName = "user")
@TypeConverters({DateConverter.class})
public class User {
    @PrimaryKey(autoGenerate = true)
    private int uid;
    @ColumnInfo(name = "first_name")
    private String mFirstName;
    @ColumnInfo(name = "last_name")
    private String mLastName;
    @ColumnInfo(name = "email")
    private String mEmail;
    @ColumnInfo(name = "mobile")
    private String mMobile;
    @ColumnInfo(name = "address")
    private String mAddress;
    @ColumnInfo(name = "image_uri")
    private String mImageUrl;
    @ColumnInfo(name = "last_update")
    private Date mLastUpdate;
    @ColumnInfo(name = "created_at")
    private Date mCreatedAt;
    public User(String mFirstName, String mLastName, String mEmail, String mMobile, String mAddress, Date mLastUpdate, Date mCreatedAt) {
        this.mFirstName = mFirstName;
        this.mLastName = mLastName;
        this.mEmail = mEmail;
        this.mMobile = mMobile;
        this.mAddress = mAddress;
        this.mLastUpdate = mLastUpdate;
        this.mCreatedAt = mCreatedAt;
    }
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getFirstName() {
        return mFirstName;
    }
    public void setFirstName(String mFirstName) {
        this.mFirstName = mFirstName;
    }
    public String getLastName() {
        return mLastName;
    }
    public void setLastName(String mLastName) {
        this.mLastName = mLastName;
    }
    public String getEmail() {
        return mEmail;
    }
    public void setEmail(String mEmail) {
        this.mEmail = mEmail;
    }
    public String getMobile() {
        return mMobile;
    }
    public void setMobile(String mMobile) {
        this.mMobile = mMobile;
    }
    public String getAddress() {
        return mAddress;
    }
    public void setAddress(String mAddress) {
        this.mAddress = mAddress;
    }
    public Date getLastUpdate() {
        return mLastUpdate;
    }
    public void setLastUpdate(Date mLastUpdate) {
        this.mLastUpdate = mLastUpdate;
    }
    public Date getCreatedAt() {
        return mCreatedAt;
    }
    public void setCreatedAt(Date mCreatedAt) {
        this.mCreatedAt = mCreatedAt;
    }
    public String getImageUrl() {
        return mImageUrl;
    }
    public void setImageUrl(String mImageUrl) {
        this.mImageUrl = mImageUrl;
    }
}

Create a database DAO for user entity

Create a DAO class to database abstraction layer for accessing user entity. like below .

package com.wave.sample.db.dao;
import com.wave.sample.db.model.User;
import java.util.List;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import static androidx.room.OnConflictStrategy.REPLACE;
/**
 * Created on : Feb 01, 2019
 * Author     : AndroidWave
 */
@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();
    @Insert(onConflict = REPLACE)
    void insertUser(User mUser);
    @Insert
    void insertAllUser(User... mUsersList);
    @Delete
    void delete(User mUser);
    @Update
    void updateUser(User mUser);
    @Query("SELECT * FROM user WHERE uid = :uId")
    User getUserById(int uId);
    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);
    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
            "last_name LIKE :last LIMIT 1")
    User findByName(String first, String last);
}

Create a database class that provide singleton instance of DB

package com.wave.sample.db;
import android.content.Context;
import com.wave.sample.db.dao.UserDao;
import com.wave.sample.db.model.User;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
/**
 * Created on : Feb 01, 2019
 * Author     : AndroidWave
 */
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    private static AppDatabase mInstance;
    private static final String DATABASE_NAME = "wave-database";
    public abstract UserDao userDao();
    public synchronized static AppDatabase getDatabaseInstance(Context context) {
        if (mInstance == null) {
            mInstance = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
                    .allowMainThreadQueries()
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return mInstance;
    }
    public static void destroyInstance() {
        mInstance = null;
    }
}

Prepare User List from Database

For now, we will insert a demo content in the database after that fetch all user list from DB and display on the RecyclerView. Open the activity_main.xml and add RecyclerView and FloatingActionButton component.

<?xml version="1.0" encoding="utf-8"?>
<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">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:listitem="@layout/item_user" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="16dp"
        android:src="@drawable/ic_person_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Create a RecyclerView Adapter for holding user list

create a xml layout with named item_user.xml  and create view for user details like profile picture name and email with delete button.

<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:background="@color/white"
    android:padding="@dimen/default_padding">
    <ImageView
        android:id="@+id/imageViewProfile"
        android:layout_width="@dimen/dp_size"
        android:layout_height="@dimen/dp_size"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:src="@drawable/user_profile_thumb_2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@drawable/user_profile_thumb_1" />
    <TextView
        android:id="@+id/textViewDisplayName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="8dp"
        android:text="@string/placeholder_name"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/textViewEmail"
        app:layout_constraintEnd_toStartOf="@+id/imageViewDelete"
        app:layout_constraintStart_toEndOf="@+id/imageViewProfile"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />
    <TextView
        android:id="@+id/textViewEmail"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="8dp"
        android:text="@string/placeholder_gmail_com"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/imageViewDelete"
        app:layout_constraintStart_toEndOf="@+id/imageViewProfile"
        app:layout_constraintTop_toBottomOf="@+id/textViewDisplayName" />
    <ImageView
        android:id="@+id/imageViewDelete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_delete" />
</androidx.constraintlayout.widget.ConstraintLayout>
Create a adapter class

Create a java class with named UserAdapter , onCreateViewHolder() methods is inflate the user item layout and onBindViewHolder() bind view with data holder.

package com.wave.sample;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.wave.sample.db.model.User;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
 * Created on : Feb 02, 2019
 * Author     : AndroidWave
 */
public class UserAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private Callback mCallback;
    private List<User> mUserList;
    public UserAdapter(List<User> usersList) {
        mUserList = usersList;
    }
    public void setCallback(Callback callback) {
        mCallback = callback;
    }
    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        holder.onBind(position);
    }
    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(
                LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false));
    }
    @Override
    public int getItemViewType(int position) {
        return 0;
    }
    @Override
    public int getItemCount() {
        if (mUserList != null && mUserList.size() > 0) {
            return mUserList.size();
        } else {
            return 0;
        }
    }
    public interface Callback {
        void onDeleteClick(User mUser);
    }
    public void addItems(List<User> userList) {
        mUserList = userList;
        notifyDataSetChanged();
    }
    public class ViewHolder extends BaseViewHolder {
        @BindView(R.id.imageViewDelete)
        ImageView imageViewDelete;
        @BindView(R.id.textViewDisplayName)
        TextView textViewName;
        @BindView(R.id.textViewEmail)
        TextView textViewEmail;
        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
        protected void clear() {
            textViewEmail.setText("");
            textViewName.setText("");
        }
        public void onBind(int position) {
            super.onBind(position);
            final User mUser = mUserList.get(position);
            if (mUser.getFirstName() != null) {
                textViewName.setText(String.format("%s %s", mUser.getFirstName(), mUser.getLastName()));
            }
            if (mUser.getEmail() != null) {
                textViewEmail.setText(mUser.getEmail());
            }
            imageViewDelete.setOnClickListener(v -> mCallback.onDeleteClick(mUser));
        }
    }
}
Here is BaseViewHolder
package com.wave.sample;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
/**
 * Created on : Jan 26, 2019
 * Author     : AndroidWave
 * Email    : info@androidwave.com
 */
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
    private int mCurrentPosition;
    public BaseViewHolder(View itemView) {
        super(itemView);
    }
    protected abstract void clear();
    public void onBind(int position) {
        mCurrentPosition = position;
        clear();
    }
    public int getCurrentPosition() {
        return mCurrentPosition;
    }
}
Fetch the data from database and display on RecyclerView.

Before fetching data we have to insert some demo content in user table after that will fetch all user list and display over the RecyclerView. Open MainActivity add below code.

Basically the following operation is doing in this activity

  • Creating a Database Instance
  • Inserting demo content
  • Initialing UserAdapter and set on the RecyclerView
  • Fetch all the user list from Database and update the adapter
  • Implement RecyclerView.Callback and set callback on adapter
  • On click delete the callback delete object and refresh the list item
package com.wave.sample;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.wave.sample.db.AppDatabase;
import com.wave.sample.db.model.User;
import java.util.ArrayList;
import java.util.Date;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity implements UserAdapter.Callback {
    @BindView(R.id.recyclerView)
    RecyclerView mRecyclerView;
    @BindView(R.id.fab)
    FloatingActionButton fab;
    AppDatabase database;
    UserAdapter mUserAdapter;
    LinearLayoutManager mLayoutManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        database=AppDatabase.getDatabaseInstance(this);
        setUp();
    }
    private void setUp() {
        mLayoutManager = new LinearLayoutManager(this);
        mLayoutManager.setOrientation(RecyclerView.VERTICAL);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mUserAdapter = new UserAdapter(new ArrayList<User>());
        mUserAdapter.setCallback(this);
        prepareDemoContent();
        mRecyclerView.setAdapter(mUserAdapter);
    }
    private void prepareDemoContent() {
        User mUser1 = new User("Ramesh", "Chandra", "ramesh@gmail.com", null, null, new Date(), new Date());
        database.userDao().insertUser(mUser1);
        User mUser2 = new User("Sachin", "Kalal", "chnada@gmail.com", null, null, new Date(), new Date());
        database.userDao().insertUser(mUser2);
        User mUser3 = new User("Amit", "Kumar", "arun@gmail.com", null, null, new Date(), new Date());
        database.userDao().insertUser(mUser3);
        User mUser4 = new User("Kapil", "sharma", "kapil@gmail.com", null, null, new Date(), new Date());
        database.userDao().insertUser(mUser4);
    }
    @Override
    protected void onResume() {
        super.onResume();
        mUserAdapter.addItems(database.userDao().getAll());
    }
    @OnClick(R.id.fab)
    public void onViewClicked() {
        AddUserActivity.startActivity(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        AppDatabase.destroyInstance();
    }
    @Override
    public void onDeleteClick(User mUser) {
        database.userDao().delete(mUser);
        mUserAdapter.addItems(database.userDao().getAll());
    }
}

Build and Run the project you will able to see some demo user in the RecyclerView. If you want to delete some item click on the delete button callback will call onDeleteClick()

Inserting a new User in database

We have to create UI for inserting a new user in the database. just go to src folder right click => New Activity with the layout is named AddUserActivity.java. Open actviity_add_user xml layout and some text input layout with the add user button

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:padding="@dimen/default_padding"
    tools:context=".AddUserActivity">
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/textInputLayoutFirstName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/textFirstName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_first_name"
            android:inputType="textPersonName" />
    </com.google.android.material.textfield.TextInputLayout>
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/textInputLayout3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayoutFirstName">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/textLastName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_last_name"
            android:inputType="textPersonName" />
    </com.google.android.material.textfield.TextInputLayout>
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/textInputLayoutEmail"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayout3">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/textEmail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress" />
    </com.google.android.material.textfield.TextInputLayout>
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/textInputLayout9"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayoutEmail">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/textPhoneNo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_phone_no"
            android:inputType="phone" />
    </com.google.android.material.textfield.TextInputLayout>
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/textInputLayout10"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayout9">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/textAddress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_address"
            android:inputType="textImeMultiLine" />
    </com.google.android.material.textfield.TextInputLayout>
    <Button
        android:id="@+id/buttonAddUser"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:background="@color/colorAccent"
        android:text="@string/add_user"
        android:textColor="@color/white"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayout10" />
</androidx.constraintlayout.widget.ConstraintLayout>

Open AddUserActvity.java and add below code

package com.wave.sample;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.wave.sample.db.AppDatabase;
import com.wave.sample.db.model.User;
import java.util.Date;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AddUserActivity extends AppCompatActivity {
    @BindView(R.id.textFirstName)
    TextInputEditText textFirstName;
    @BindView(R.id.textLastName)
    TextInputEditText textLastName;
    @BindView(R.id.textEmail)
    TextInputEditText textEmail;
    @BindView(R.id.textPhoneNo)
    TextInputEditText textPhoneNo;
    @BindView(R.id.textAddress)
    TextInputEditText textAddress;
    @BindView(R.id.buttonAddUser)
    Button buttonAddUser;
    @BindView(R.id.textInputLayoutFirstName)
    TextInputLayout textInputLayoutFirstName;
    @BindView(R.id.textInputLayoutEmail)
    TextInputLayout textInputLayoutEmail;
    AppDatabase database;
    public static void startActivity(Context mContext) {
        Intent mIntent = new Intent(mContext, AddUserActivity.class);
        mContext.startActivity(mIntent);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_user);
        ButterKnife.bind(this);
        database = AppDatabase.getDatabaseInstance(this);
    }
    @OnClick(R.id.buttonAddUser)
    public void onViewClicked() {
        if (textFirstName.getText().toString().trim().isEmpty()) {
            textInputLayoutFirstName.setError(getString(R.string.error_msg_firstname));
            return;
        }
        if (textEmail.getText().toString().trim().isEmpty()) {
            textInputLayoutEmail.setError(getString(R.string.error_msg_email));
            return;
        }
        User mUser = new User(textFirstName.getText().toString(), textLastName.getText().toString(), textEmail.getText().toString(), textPhoneNo.getText().toString(), textAddress.getText().toString(), new Date(), new Date());
        database.userDao().insertUser(mUser);
        finish();
    }
    @Override
    protected void onDestroy() {
        AppDatabase.destroyInstance();
        super.onDestroy();
    }
}

Build and Run the project and selected targets device. as usual you MainActivity.java will open. Click FloatingActionButton and go the AddUserActivity fill user detail and click on Add. The user is inserted in database and displaying on the RecyclerView such as video in demo application.

Download Source Code – Working with Room Persistence Library

6 Comments

  1. > Task :app:compileDebugJavaWithJavac
    Gradle may disable incremental compilation as the following annotation processors are not incremental: butterknife-compiler-10.1.0.jar (com.jakewharton:butterknife-compiler:10.1.0), room-compiler-2.0.0.jar (androidx.room:room-compiler:2.0.0).
    Consider setting the experimental feature flag android.enableSeparateAnnotationProcessing=true in the gradle.properties file to run annotation processing in a separate task and make compilation incremental.
    error: cannot access Publisher
      class file for org.reactivestreams.Publisher not found
      Consult the following stack trace for details.
    
    
    1 error
    
    
    > Task :app:compileDebugJavaWithJavac FAILED
    
    
    FAILURE: Build failed with an exception.
    
    
    * What went wrong:
    Execution failed for task ':app:compileDebugJavaWithJavac'.
    > Compilation failed; see the compiler error output for details.
    
    
    
  2. Firts, thank you!
    Is the additional material (images ecc.) available somewhere?

  3. Thank you so much. Your article is very informative for me.
    I wrote your code but I got a error.
    I have no idea how to fix it. Can you help me?

    Caused by: java.lang.NullPointerException: Attempt to invoke interface method ‘void com.ogrg.techtown.prac_room.UserDao.insertUser(com.ogrg.techtown.prac_room.User)’ on a null object reference
    at com.ogrg.techtown.prac_room.MainActivity.prepareDemoContent(MainActivity.java:55)
    at com.ogrg.techtown.prac_room.MainActivity.setUp(MainActivity.java:47)
    at com.ogrg.techtown.prac_room.MainActivity.onCreate(MainActivity.java:37)

    • might be you not init database=AppDatabase.getDatabaseInstance(this); part

Write A Comment