如何在Kotlin中简化该单例以进行Android房间数据库初始化?
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
}
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
答案 0 :(得分:2)
您可以使用数组文字([]
而不是arrayOf
,并且可以使用elvis运算符进行空检查。参见here。
@Database(entities = [Book::class, User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context) {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
由于需要实例,因此必须将其保存在某个位置,因此使用companion object
对我来说似乎是一个合理的解决方案。
如果您不希望将实例保存在AppDatabase
中,也可以使用一个对象(在Kotlin中是单例)。
object AppDatabaseProvider {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context) {
// ...
}
fun destroyInstance() {
INSTANCE = null
}
}
这两个都是在Kotlin中处理静态数据的选项,但是您不会比这更短。
答案 1 :(得分:1)
您的解决方案基本上是可以的。
使用数组文字是一种选择,正如@Willi Mentzel指出的那样,如果您喜欢它的外观,它会使您的代码短一些。
但是,用于获取单例实例的此代码是错误的:
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context) = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
getInMemoryDatabase
函数从不为INSTANCE
分配值,这意味着它将永远为null
,并且每次调用该函数时,右手猫王操作员的侧面将被评估并返回。这意味着每次都会有一个新实例-您只需使用此代码创建一个工厂,而不是拥有一个单例。
您可以使用Elvis运算符稍微缩短原始代码:
fun getInMemoryDatabase(context: Context): AppDatabase {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
尽管这样,在第一个调用之后,每次调用都会给它自己额外分配INSTANCE
,我认为保存那几行可能不值得,因为您的原始代码只有一个常规的null支票比这更容易阅读。
答案 2 :(得分:0)
也许会有进步,请尝试按照以下步骤
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
return INSTANCE :? Room.inMemoryDatabaseBuilder(context, this).build()
}
fun destroyInstance() {
INSTANCE = null
}
}
}