gpt4 book ai didi

android - 如何在 Android ViewModel 中等待多个作业?

转载 作者:行者123 更新时间:2023-11-30 04:59:33 25 4
gpt4 key购买 nike

给定以下组件

data class Account(val name: String)

data class GetAccountRequest(val name: String)

@Dao
interface AccountDao {
@Query("SELECT * FROM accounts ORDER BY name ASC")
fun all(): LiveData<List<Account>>
}

interface AccountOperations {
@GET("/foo/account")
suspend fun getAccount(@Body request: GetAccountRequest): Account
}

class AccountRepository(private val dao: AccountDao, private val api: AccountOperations) {
val accounts: LiveData<List<Account>> = dao.all()

suspend fun refresh(name: String) {
val account = api.getAccount(GetAccountRequest(name))
dao.insert(account)
}
}

我正在开发一个使用这些组件的 Android 应用程序(由用于数据库的 Room 和用于 API 访问的 Retrofit 提供支持)。

在我的 ViewModel 中,我维护了一个列出所有帐户的 RecyclerView。我允许用户手动刷新该列表。相应的(部分)ViewModel 如下所示:

fun refresh() {
viewModelScope.launch {
repository.accounts.value?.forEach {
launch { repository.refresh(it.name) }
}
}
Timber.i("Done refreshing!")
}

我确实希望刷新并行更新所有帐户,这就是我使用 launch 的原因。我还决定在 ViewModel 中而不是在存储库中执行此操作,因为这需要在存储库中启动一个新的协程。每个 this post不鼓励,因为存储库没有自然的生命周期。

上面的函数 refresh 是从 UI 调用的,并在更新 RecyclerView 时显示刷新指示器。所以我想在所有帐户更新后停止此指示器。

我上面显示的代码没有这样做,因为它会启动所有更新,然后在所有更新完成之前打印日志语句。结果,虽然仍有更新,但刷新指示器消失了。

所以我的问题(最后)是:我如何重构代码以使其并行运行所有更新,但确保 refresh 不会在所有更新完成之前返回?

编辑#1

回到我想要实现的目标:在 View 更新时显示刷新指示器,我想到了以下内容(更改了 ViewModel 中的 refresh 函数):

fun refresh() {
viewModelScope.launch {
try {
coroutineScope {
_refreshing.value = true
repository.accounts.value?.map { account ->
async {
repository.refresh(account.name)
}
}
}
} catch (cause: CancellationException) {
throw cause
} catch (cause: Exception) {
Timber.e(cause)
} finally {
_refreshing.value = false
}
}
}

ViewModel 在刷新时公开一个 LiveData, fragment 可以观察它以显示或隐藏微调器。这似乎可以解决问题。但是,它仍然感觉不对,我感谢任何改进的解决方案。

最佳答案

为了await所有并行refresh()操作,只需使用awaitAll():

coroutineScope.launch {
_refreshing.value = true

repository.accounts.value?.map { account ->
async {
repository.refresh(account.name)
}
}.awaitAll()

_refreshing.value = false
}

此外,不建议用 try/catch 包裹协程。您可以阅读更多关于此的信息 here .

关于android - 如何在 Android ViewModel 中等待多个作业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58475211/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com