【发布时间】:2021-08-31 15:47:02
【问题描述】:
我正在使用 RoomDatabase,在设置了我的 DAO、数据库和实体类之后,我需要找到一种方法来获取 RoomDatabase 实例,但在文档中,我看到了:
如果您的应用在单个进程中运行,则应遵循单例 实例化 AppDatabase 对象时的设计模式。每个 RoomDatabase 实例相当昂贵,您很少需要访问 到单个进程中的多个实例。
所以从Udacity 课程中我看到有多种方法可以做到这一点:第一个:
private lateinit var INSTANCE: MainDBForObjects
fun getDatabase(context: Context): MainDBForObjects{
if (!::INSTANCE.isInitialized){
INSTANCE = Room.databaseBuilder(
context,
MainDBForObjects::class.java, "database"
).fallbackToDestructiveMigration()
.build()
}
return INSTANCE
}
另一个是来自数据库抽象类的伴随对象:
companion object {
@Volatile
private var INSTANCE: SleepDatabase? = null
fun getInstance(context: Context): SleepDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
那么这两者之间有什么重要区别吗?是不是一个比另一个好?
【问题讨论】:
-
第一种方法不是线程安全的,第二种方法也是双重检查锁定的错误实现,因此尽管它是线程安全的,但即使实例是线程安全的,也会产生更高的同步成本(获取锁)已经初始化了
-
您能否将其添加为答案以及正确的实现?
标签: android singleton android-room