The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
The library helps you create a cache of your app’s data on a device that’s running your app. This cache, which serves as your app’s single source of truth, allows users to view a consistent copy of key information within your app, regardless of whether users have an internet connection.
To import Room into your Android project, add these lines to your module gradle:
implementation "android.arch.persistence.room:runtime:1.0.0" annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
You also must add maven to your project gradle:
allprojects{ repositories{ maven { url 'https://maven.google.com' } } }
Room shortens job of fetching and inserting data drastically. To be able to put data into database, you must make interface with methods intended for those operations:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.arch.persistence.room.Dao; import android.arch.persistence.room.Insert; import android.arch.persistence.room.Query; import java.util.List; @Dao public interface DatabaseInterface { @Query("SELECT * FROM todolistitem") List<TodoListItem> getAllItems(); @Insert void insertAll(TodoListItem... todoListItems); }
Please note that you must use List<> as your initial type for holding the objects and then cast that list into ArrayList.
Next we need a abstract class for defining the database, setting the rules, descriptions, etc:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.arch.persistence.db.SupportSQLiteOpenHelper; import android.arch.persistence.room.Database; import android.arch.persistence.room.DatabaseConfiguration; import android.arch.persistence.room.InvalidationTracker; import android.arch.persistence.room.RoomDatabase; @Database(entities = {TodoListItem.class},version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract DatabaseInterface databaseInterface(); @Override protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) { return null; } @Override protected InvalidationTracker createInvalidationTracker() { return null; } }
In this tutorial, we make a simple to-do application. To-do items consists of task title and task time. That is why we need an model class for these tasks:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.arch.persistence.room.ColumnInfo; import android.arch.persistence.room.Entity; import android.arch.persistence.room.PrimaryKey; @Entity public class TodoListItem { @PrimaryKey(autoGenerate = true) private int id; @ColumnInfo(name = "time") private String time; @ColumnInfo(name="title") private String title; public TodoListItem(){ } public TodoListItem(String time, String title) { this.time = time; this.title = title; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
Here we are putting marks for certain data so Room knows what to do with it:
@Entity – marks the objects class which will be stored into database
@PrimaryKey(autoGenerate = true) – talks for itself
@ColumnInfo(name = “time”) – this means that this attribute of object will be stored into database. If there wasn’t this mark, this attribute wouldn’t be stored.
Next, we will make a layout for our main activity which will be displaying items in the recyclerview:
<?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="pdf.tutorials.virtuoza.virtuozatutorials.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_centerHorizontal="true" android:textColor="#000" android:textSize="25sp" android:text="To-do list:" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_marginTop="60dp" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="@dimen/fab_margin" app:srcCompat="@android:drawable/ic_input_add" /> </RelativeLayout> </android.support.constraint.ConstraintLayout>
Next, we make a item row for our RecyclerView:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView android:elevation="4dp" android:layout_margin="8dp" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:padding="15dp" android:gravity="center_horizontal" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:textAlignment="center" android:layout_gravity="center_horizontal" android:id="@+id/name" android:text="asfs" android:textSize="18sp" android:textStyle="bold" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="ffsa" android:textSize="18sp" android:textAlignment="center" android:layout_gravity="center_horizontal" android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </android.support.v7.widget.CardView>
… layout for adding items activity:
<?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" android:padding="24dp" tools:context="pdf.tutorials.virtuoza.virtuozatutorials.AddItemActivity"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="24sp" android:text="Add Item:" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputEditText android:id="@+id/name" android:hint="To do:" android:layout_width="match_parent" android:layout_height="wrap_content"/> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputEditText android:id="@+id/time" android:hint="Time:" android:layout_width="match_parent" android:layout_height="wrap_content"/> </android.support.design.widget.TextInputLayout> <Button android:layout_marginTop="50dp" android:text="SAVE" android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </android.support.constraint.ConstraintLayout>
Next, we will program the activities. Lets start with Main Activity. It holds the recyclerview, reads the data from database and has a button for running the AddItemActivity.
package pdf.tutorials.virtuoza.virtuozatutorials; import android.arch.persistence.room.Room; import android.content.Intent; import android.os.AsyncTask; import android.support.design.widget.FloatingActionButton; import android.support.text.emoji.EmojiCompat; import android.support.text.emoji.bundled.BundledEmojiCompatConfig; import android.support.text.emoji.widget.EmojiEditText; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Button; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { FloatingActionButton fab; public static RecyclerView recyclerView; public static RecyclerView.Adapter adapter; List<TodoListItem> items; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //whenever the activity is started, it reads data from database and stores it into // local array list 'items' final AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class,"production") .build(); //it is very bad practice to pull data from Room on main UI thread, // that's why we create another thread which we use for getting the data and displaying it Runnable r = new Runnable(){ @Override public void run() { items = db.databaseInterface().getAllItems(); recyclerView= (RecyclerView)findViewById(R.id.recyclerview); recyclerView.setLayoutManager(new LinearLayoutManager(getApplication())); adapter= new UserAdapter(items); adapter.notifyDataSetChanged(); recyclerView.setAdapter(adapter); } }; Thread newThread= new Thread(r); newThread.start(); fab=(FloatingActionButton)findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(MainActivity.this,AddItemActivity.class); startActivity(i); finish(); } }); } }
This is our custom adapter for recyclerview from Main Activity:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; import java.util.List; /** * Created by azem on 12/22/17. */ public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> { List<TodoListItem> items; public UserAdapter(List<TodoListItem> items) { this.items = items; } @Override public UserAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_row,parent,false); return new ViewHolder(view); } @Override public void onBindViewHolder(UserAdapter.ViewHolder holder, int position) { holder.name.setText(items.get(position).getTitle()); holder.time.setText(items.get(position).getTime()); } @Override public int getItemCount() { return items.size(); } public class ViewHolder extends RecyclerView.ViewHolder{ public TextView name; public TextView time; public ViewHolder(View itemView) { super(itemView); name = itemView.findViewById(R.id.name); time= itemView.findViewById(R.id.time); } } }
And this is the activity where we add new items. Pay attention to listener on the button:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.arch.persistence.room.Room; import android.content.Intent; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class AddItemActivity extends AppCompatActivity { EditText todo; EditText time; Button button; AppDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_item); db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class,"production") .build(); todo = (EditText) findViewById(R.id.name); time = (EditText) findViewById(R.id.time); button = (Button)findViewById(R.id.button); final AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class,"production") .build(); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!todo.getText().toString().equals("") && !time.getText().toString().equals("")){ final TodoListItem todoListItem= new TodoListItem(todo.getText().toString(),time.getText().toString()); //save the item before leaving the activity AsyncTask.execute(new Runnable() { @Override public void run() { db.databaseInterface().insertAll(todoListItem); } }); Intent i = new Intent(AddItemActivity.this,MainActivity.class); startActivity(i); finish(); } } }); } }
And that is it. This is how you store the objects to Room database and read them.
Share with your friends