我正在使用Coroutines
对我的db
数据库执行Room
操作
我已经为协程创建了一个助手,如下所示:
object Coroutines {
fun main(work: suspend(() -> Unit)) = CoroutineScope(Dispatchers.Main).launch {
work()
}
fun io(work: suspend(() -> Unit)) = CoroutineScope(Dispatchers.IO).launch {
work()
}
}
以下是我在主线程上调用插入操作的代码
class LocalListViewModel(private val localVideoRepository: LocalVideoRepository) : ViewModel() {
val localVideos = MutableLiveData<ArrayList<LocalVideo?>?>()
fun insertAllLocalVideo() {
Coroutines.main {
localVideoRepository.insertLocalVideo(localVideos.value)
}
}
}
class LocalVideoRepository(private val db: AppDatabase) {
suspend fun insertLocalVideo(localVideos: ArrayList<LocalVideo?>?) =
db.getLocalVideoDao().insertLocalVideos(localVideos)
}
@Dao
interface LocalVideoDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertLocalVideos(localVideoList: ArrayList<LocalVideo?>?)
}
@Database(entities = [LocalVideo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun getLocalVideoDao(): LocalVideoDao
companion object {
@Volatile
private var instance: AppDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
instance ?: buildDatabase(context).also { instance = it }
}
private fun buildDatabase(context: Context) = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
context.getString(R.string.psplayer_db)
).build()
}
}
我不了解的是,即使在调用Coroutines
的主线程之后,数据也已成功插入而不是崩溃了?
答案 0 :(得分:0)
有关深入解答,请查看CoroutinesRoom.execute
帮助器:
suspend fun <R> execute(
db: RoomDatabase,
inTransaction: Boolean,
callable: Callable<R>
): R {
if (db.isOpen && db.inTransaction()) {
return callable.call()
}
// Use the transaction dispatcher if we are on a transaction coroutine, otherwise
// use the database dispatchers.
val context = coroutineContext[TransactionElement]?.transactionDispatcher
?: if (inTransaction) db.transactionDispatcher else db.queryDispatcher
return withContext(context) {
callable.call()
}
}
除非它已经在事务中,否则它将始终将实际查询的执行转移到IO优化的调度程序上。因此,无论调用上下文如何,suspend
房间定义将永远不会在应用程序线程上执行。