Ioa*_* P. 3 android kotlin android-room kotlin-coroutines
我正在使用 Room 创建一个简单的应用程序。我创建了一个 DAO 接口:
interface ItemDao {
@Insert(onConflict = IGNORE)
fun addItem(item: Item)
}
Run Code Online (Sandbox Code Playgroud)
以及存储库接口:
interface ItemRepository {
fun addItem(item: Item)
}
Run Code Online (Sandbox Code Playgroud)
下面是该函数的实现:
class ItemRepositoryImpl(
private val itemDao: ItemDao
) : ItemRepository {
override fun addItem(item: Item) = itemDao.addItem(item)
}
Run Code Online (Sandbox Code Playgroud)
在 ViewModel 类中,我使用 viewModelScope 启动一个协程:
class ItemViewModel @Inject constructor(
private val repo: ItemRepository
) : ViewModel() {
fun addItem(item: Item) = viewModelScope.launch(Dispatchers.IO) {
repo.addItem(item)
}
}
Run Code Online (Sandbox Code Playgroud)
当我addItem
从 UI 调用时,该项目已成功添加到 Room。现在的问题是,是否必须将ItemDao接口内的addItem函数设置为挂起函数?如果是,为什么?我真的很困惑。
编辑:
这是我创建数据库实例的方法:
fun provideItemDb(
@ApplicationContext
context : Context
) = Room.databaseBuilder(
context,
ItemDb::class.java,
"item_table"
).build()
Run Code Online (Sandbox Code Playgroud)
挂起函数不是必需的,但如果您不将函数标记为suspend
,那么它们会阻塞,因此在主线程上调用它们是不安全的。
如果您正在使用协程,则调用阻塞 IO 函数是安全的,但前提是您当前的 CoroutineContext 未使用Dispatchers.Main
. 您目前没有使用suspend
函数,因为您正在使用 运行协程Dispatchers.IO
,因此该函数是从主线程调用的。
如果您正在使用协程,为了代码简单起见,您应该始终对它们进行标记suspend
,以便这些函数更容易使用且更通用。例如,想象一下,如果您还想使用新添加项目的行 ID 更新 LiveData。(您可以通过在 DAO 函数中返回 Long 来完成此操作。)
suspend
如果您在 DAO 中使用,您的函数可以是:
fun addItem(item: Item) = viewModelScope.launch {
_latestRowLiveData.value = repo.addItem(item)
}
Run Code Online (Sandbox Code Playgroud)
如果您没有suspend
在 DAO 中使用,您的函数必须是以下更复杂的实现之一:
fun addItem(item: Item) = viewModelScope.launch {
_latestRowLiveData.value = withContext(Dispatchers.IO) { repo.addItem(item) }
}
// or
fun addItem(item: Item) = viewModelScope.launch(Dispatchers.IO) {
_latestRowLiveData.postValue(repo.addItem(item))
}
// or
fun addItem(item: Item) = viewModelScope.launch(Dispatchers.IO) {
val rowId = repo.addItem(item)
withContext(Dispatchers.Main) {
_latestRowLiveData.value = rowId
}
}
Run Code Online (Sandbox Code Playgroud)
现在想象一个想要执行一系列不同操作的函数。DAO 的非挂起版本会导致 ViewModel 中的协程看起来非常混乱(因此容易出现错误)。
归档时间: |
|
查看次数: |
653 次 |
最近记录: |