And*_*Dev 1 android deferred kotlin android-room kotlin-coroutines
我正在尝试使用async & awaitinside从 Room Database 获取数据,Coroutine Scope但在返回值时遇到问题。
这是我的代码:
fun getUserFromDB():Profile {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
CoroutineScope(Dispatchers.IO).launch {
return profileDao.getUserProfile().await()
}
}
Run Code Online (Sandbox Code Playgroud)
道:
@Query("SELECT * FROM PROFILE LIMIT 1")
suspend fun getUserProfile():Deferred<Profile>
Run Code Online (Sandbox Code Playgroud)
在这里我想从方法返回 userProfile 但我不能在范围内这样做,如果我从Coroutine scope.
注意:我不是在这里遵循 MVVM 模式,而是做一个简单的例子。
这里有一些错误,但我将首先解决主要问题。
fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
CoroutineScope(Dispatchers.IO).launch {
val userProfile = profileDao.getUserProfile().await()
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
在 中getUserFromDB,从launch异步执行getUserFromDB并且在您返回之前不会完成。
getUserFromDB为挂起函数。(强烈推荐)suspend fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
val userProfile = withContext(Dispatchers.IO) {
profileDao.getUserProfile().await()
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
runBlocking.fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
val userProfile = runBlocking(Dispatchers.IO) {
profileDao.getUserProfile().await()
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
getUserProfile不应该返回Deferred<Profile>(特别是如果它已经挂起),因为这是一个不安全的原语,它应该只返回Profile。这样您就不会意外引入不需要的并发性,也不必编写await().@Query("SELECT * FROM PROFILE LIMIT 1")
suspend fun getUserProfile(): Profile
fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
CoroutineScope(Dispatchers.IO).launch {
val userProfile = profileDao.getUserProfile() /* .await() */
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
Dispatchers.IO),在主线程/调度程序中调用是安全的。此答案中的更多信息为什么 querySkuDetails 需要在 IO 上下文中运行?.fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
CoroutineScope(/* Dispatchers.IO */).launch {
val userProfile = profileDao.getUserProfile().await()
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
CoroutineScope没有取消它,你应该只是GlobalScope用来减少分配的数量。人们说“避免使用GlobalScope.”,这是真的,但你同样应该避免CoroutineScope在不取消它们的情况下创建s(我认为它更糟)。fun getUserFromDB() {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
GlobalScope.launch(Dispatchers.IO) {
val userProfile = profileDao.getUserProfile().await()
}
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
我已经对我的答案进行了结构化,以便您可以在准备好时独立应用每个更改。如果您只想要所有更改的总和,那么就在这里。
@Query("SELECT * FROM PROFILE LIMIT 1")
suspend fun getUserProfile(): Profile
suspend fun getUserFromDB(): Profile {
val profileDao = AppDatabase.getDatabase(context).getProfileDao()
val userProfile = profileDao.getUserProfile()
return userProfile
}
Run Code Online (Sandbox Code Playgroud)
快乐编码。:)
| 归档时间: |
|
| 查看次数: |
2404 次 |
| 最近记录: |