I'm trying to use Room as singleton so I didn't have to invoke Room.databaseBuilder()
-which is expensive- more than once.
@Database(entities = arrayOf(
Price::class,
StationOrder::class,
TicketPrice::class,
Train::class,
TrainCategory::class
), version = 2)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun dao(): TrainDao
companion object {
fun createDatabase(context: Context): AppDatabase
= Room.databaseBuilder(context, AppDatabase::class.java, "trains.db").build()
}
}
Note:
- Can't use Object because Room requires using
abstract class
. - singleton must be thread safe because multiple threads might access it at the same time.
- must be able to take
Context
as an argument.
I have looked at all similar StackOverflow questions and none of them satisfy my requirements
Singleton with argument in Kotlin isn't thread-safe
Kotlin - Best way to convert Singleton DatabaseController in Android isn't thread-safe
Kotlin thread save native lazy singleton with parameter uses object
After some research, I found that I have two options.
I considered implementing one of them, but this didn't felt right for Kotlin - too much boilerplate code.
After more research, I stumbled upon this great article which provides an excellent solution, which uses Double-checked locking but in an elegant way.
From the article:
Extra: if you want Singleton with two arguments