When prepopulated data is required so that the user does not see empty screen on start, there are several ways to achieve this.
Android API provides ways to use prepackaged database files on database creation.
See : Prepopulate your Room database
I used alternative way to prepopulate database without prepackaged database file.
@Database(entities = [Task::class, TaskRecord::class], version = 1)
abstract class TaskDatabase : RoomDatabase() {
abstract fun taskDao() : TaskDao
companion object {
private var instance : TaskDatabase? = null
fun getInstance(context: Context): TaskDatabase {
return instance ?: synchronized(this){
instance ?: buildDatabase(context).also { instance = it }
}
}
private fun buildDatabase(context: Context) : TaskDatabase {
return Room.databaseBuilder(
context.applicationContext,
TaskDatabase::class.java,
"task.db"
).addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
val taskDao = getInstance(context).taskDao()
val defaultTask = Task("Default", 25.minutes, 5.minutes, 15.minutes, 5, Primary)
taskDao.insertNewTask(defaultTask)
}
}
}).build()
}
}
}
The reasons I've done it like this is that
First, I did not have database configuration tool to modify data in .db
file.
Second, I wanted to do this in code so it's easier to see what data goes in.
Third, I did not need to insert large data, so executing on creation would not affect performance.
Also, I used singleton object of database class instead of just making an instance with .build()
in repository.
This was for accessibility of dao.
On database initialization, dao object is not accessible in callback.
But using bit of trick, insertion can be done with dao.