Room Database in android with Kotlin-Coroutines
The Room is an Android persistence library which provides an abstraction layer over SQLite.
Room is an ORM (Object Relational Mapper) for mapping our database objects in android. It is part of the Architecture Components.
This is the perfect choice when your application needs to store the user’s data locally to handle the case when the user goes offline or any network failure happens.
Pre-requisites
- SQLite database and the SQLite query language
- Basic idea of Kotlin-Coroutines (don’t know what’s this, read here)
- Comfortable with Classes and Objects in Kotlin
Now, let’s get start the code
Create a new android project
- Go to File>New>New Project
- Select Empty Activity and click Next
- Give your project a suitable name and enter package name (or leave it as default)
- Select Kotlin as Language and choose Minimum SDK (you can get help from Help me choose)
- Click Finish
- After some processing time, the Android Studio main window will appear (make sure you have active internet connection)
Add dependencies
Open build.gradle
(app level) file
and add this in dependencies{}
Note: Make sure that id 'kotlin-kapt'
is added in plugins{}
or you will get a gradle exception while syncing the project.
Create a Model or Entity
It is the table for the database having Entity
annotation. Room creates a separate table for each class that has entity annotation with field of the class as columns of the table. So, must create a Primary Key and give a name to the table.
Follow the steps
- Create a new data class
FoodItem
- Annotate with
@Entity
with table name before class definition - Create fields
name
andprice
- Make name primary key and give both fields suitable column name
Code for the entity class :
Note: Make sure that when you use this entity then for every object you create, give unique string to the Name
otherwise the new data will override the old data as name is the primary key of the table.
Create DAO (Data Access Object)
Here, we are going to associate SQL queries with the function calls like
- Getting all food items alphabetically
- Add new food item
- Delete a food item
Follow these steps to create DAO
- Create a kotlin interface
FoodItemDao
- Annotate with
@Dao
- Create functions for above tasks in the Dao interface
Code for the DAO:
Flow<>
from kotlin-coroutines is used to observe data changes in the database. Using a return value of type Flow in the method description, Room generates all necessary code to update the Flow when the database is updated. When Room queries return Flow, the queries are automatically run asynchronously on a background thread.suspend fun
are generally used to handle long running tasks without blocking the main thread. Learn more about suspend function here@Insert
and@Delete
are DAO method annotations where SQL query is not required but there is no annotation to get a list of items so we have to add query manually for this using@Query
OnConflictStrategy.IGNORE
ignores the conflict when adding new item if the item is already present in the table.
Implement the Room Database
Room is a database layer on top of an SQLite database. Room uses the DAO to issue queries to its database.
Create an abstract class FoodItemRoom
and extent it with RoomDatabase()
and add this code to the class:
version
and exportSchema
are mainly used when we have to make Database Migrations, that's why exportSchema
is set to false here.
In case you want to learn more about Migrations
Create Repository
The repository class is responsible for interacting with the Room database and will need to provide methods that use the DAO to insert, delete and query items.
- Create a kotlin class
FoodItemRepository
- Pass
FoodItemDao
as an argument - Add this code in the class
In insert()
and delete()
functions we are directly inserting and deleting food item without ensuring that long running tasks shouldn't perform on the main thread because room by default runs suspend
queries off the MainThread and we are not required anything else to implement.
Implement ViewModel
The ViewModel
is responsible to provide data to the UI and survive configuration changes such as screen rotations. Learn more about view model
- Create a kotlin class
FoodItemViewModel
and extend withViewModel()
- Now add this code
- To launch a new coroutine ViewModels have a coroutine scope based on their lifecycle called
viewModelScope
, is used here. - Created the ViewModel and implemented a
ViewModelProvider.Factory
that gets as a parameter the dependencies needed to createFoodItemViewModel
: theFoodItemRepository
Instantiate Repository and Database
To have only one instance of the database and of the repository in the entire application create them as members of the Application
class.
- Create a new class
MyApplication
that extendsApplication
- Here’s the code for the application class
Note: Do not forget to update AndroidManifest.xml
, set MyApplication
as application android:name
All done with the implementation of Room. Now only thing remaining is connection of data with the UI.
Manage Data in Activity
- Open
MainActivity.kt
and create viewModel beforeonCreate()
function of the activity
Now you can call the functions we have created in FoodItemViewModel
like get all food items, add new item, delete an item.
- Get All Items
In onCreate()
function of the activity add this code
- Add New Item and Delete old Item
When you want to add new item or to delete an existing item then use foodItemViewModel
to access all the functions.
Tip: After adding or deleting items from the database you don’t need to update the UI because viewModel observe the data changes in the database and by default execute observer
foodItemViewModel.allFoodItems.observe()
and whatever task you have perform in theobserve()
, room will execute that task automatically.
Isn’t it just wow…
.
Showing Data from Database
This is just a demo to test that data is saved in room database or not.
This code should be in onCreate()
method of MainActivity.kt
after setContentView()
Tip: If the
foodItemList
returned by thefoodItemViewModel
is null, this means that no data is present in Room and you have to first insert items in the database.
After running the app this dialog appears
According to the query we write in DAO class for getting all the food items, the list of food items is sorted alphabetically.
Summing up…
This post has demonstrated how to use Room Persistence Library to store data in a local database.
If you want a deep dive in Room Database then you should refer this Codelab
Thank you for reading 🙏
Keep learning, Keep growing 🙂