Using Hilt with Room DB
This story describes how to use Hilt dependency injection using Room DB along with Co routines in Kotlin.
This project uses MVVM and Kotlin . This project contains 2 screens that represents a list to display data from Room DB and also another screen that allows to add a new row in DB.
Step 1 :
Create a class that extends Application class with @HiltAndroidApp annotation
@HiltAndroidApp
class RoomDBApplication : Application() {
}
Step 2: Create an Object class that is annotated with @Module
This class contains 2 methods with @Provides annotation that provides dependencies .
One method returns the Dao object to be used as dependency in Repository class.
The second method provides repository that is used as dependency in View Model
@InstallIn(ApplicationComponent::class)
@Module
object DBModule {
@Provides
fun provideStudentDao(@ApplicationContext appContext: Context) : StudentDao {
return StudentDB.getInstance(appContext).studentDao
}
@Provides
fun provideStudentDBRepository(studentDao: StudentDao) = RoomDBRepository(studentDao)
}
Step 3:
Creating Room Data Base
Create a data class annotation with @entity to represent a Table in Room as below:
package com.hilt.room.db
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "student")
data class Student (
@PrimaryKey(autoGenerate = true)
val studentId : Long = 0L,
val fName : String,
val lname : String,
val standard : String,
val age : Int
)
Create an interface annotated with @@Dao that represents Database operations
package com.hilt.room.db
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface StudentDao{
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(student: Student) : Long
@Query("select * From student ORDER BY studentId ASC")
fun fetch() : LiveData<MutableList<Student>>
}
Create an abstract class that extends RoomDatabase()
@Database(entities = [Student::class], version = 1, exportSchema = false)
abstract class StudentDB : RoomDatabase() {
/**
* Connects the database to the DAO.
*/
abstract val studentDao: StudentDao
companion object {
@Volatile
private var INSTANCE: StudentDB? = null
fun getInstance(context: Context): StudentDB {
// Multiple threads can ask for the database at the same time, ensure we only initialize
// it once by using synchronized. Only one thread may enter a synchronized block at a
// time.
synchronized(this) {
// Copy the current value of INSTANCE to a local variable so Kotlin can smart cast.
// Smart cast is only available to local variables.
var instance = INSTANCE
// If instance is `null` make a new database instance.
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
StudentDB::class.java,
"sleep_history_database"
)
// Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this lesson. You can learn more about
// migration with Room in this blog post:
// https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929
.fallbackToDestructiveMigration()
.build()
// Assign INSTANCE to the newly created database.
INSTANCE = instance
}
// Return instance; smart cast to be non-null.
return instance
}
}
}
}
Step 4: ViewModel
View Model contains 2 methods to insert and fetch data from Room DB through Repository which is sent as dependency for ViewModel.
The dependency is injected using @ViewModelInject annotation and repository which is dependency is passed as constructor as below.
class StudentViewModel @ViewModelInject constructor(private val roomDBRepository: RoomDBRepository) :
ViewModel(),LifecycleObserver {
Step 5:
RoomDBRepository:
For this class Dao is injected as constructor dependency to access DB methods
class RoomDBRepository @Inject constructor(private val studentDao: StudentDao){
suspend fun insertStudentData(student: Student) = studentDao.insert(student)
suspend fun fetchStudents() = studentDao.fetch()
}
The above 2 screens represent a list that displays data from the Room DB and the floating button below launches a screen to add a new row to the DB.
The below is the code related to the above in GitHub:
Also the below is the medium link that code and steps to make webservice calls using Hilt