gpt4 book ai didi

android - 协程中的范围混淆

转载 作者:IT老高 更新时间:2023-10-28 13:42:23 31 4
gpt4 key购买 nike

我有一个用例,我想使用协程,但有点困惑如何实现它。

具有范围并绑定(bind)到 UI 生命周期并从存储库调用 API 的 ViewModel:

class UserViewModel(): CoroutineScope {

private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job

fun showUser() {
launch {
val user = repo.getUser()
livedata = user
}
}

fun onClean() {
job.cancel()
}
}

存储库使用协程构建网络调用,如下所示:

suspend fun getUser() = GlobalScope { ... }

用例是,一旦从 ViewModel 调用 API,就需要始终完全执行存储库功能,因为我们需要捕获来自服务器的所有网络响应。

如何确保存储库中的协程始终执行但 ViewModel 协程将被取消以避免 View 模型被清除后的内存泄漏?

最佳答案

根据 GlobalScope 的文档,我认为我们可以依靠使用全局 CoroutineScope 启动的协程始终执行。文档说:

Global scope is used to launch top-level coroutines which are operating on the whole application lifetime and are not cancelled prematurely.

我已经实现了一些测试代码,当 jobUserViewModel 内被取消时,存储库中的协程继续执行。这是我的评论代码:

class UserViewModel(): CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job

fun showUser() {
launch {
val repo = Repository()
val userDeferred = repo.getUser()
// if onClean() is called before the coroutine in Repository finishes,
// this line will not be called, but coroutine in Repository will continue executing
val result = userDeferred.await() // wait for result of I/O operation without blocking the main thread
}
}

fun onClean() {
job.cancel()
}
}

class Repository {
fun getUser() = GlobalScope.async {
delay(4000)
// this line is executed no matter whether the job in UserViewModel was canceled or not
"User returned"
}
}

另外我们可以减少 showUser() 函数:

fun showUser() = repo.getUser().then(this) {
// `it` contains the result
// here is the main thread, use `it` to update UI
}

使用扩展函数然后:

fun <T> Deferred<T>.then(scope: CoroutineScope = GlobalScope, uiFun: (T) -> Unit) {
scope.launch { uiFun(this@then.await()) }
}

如果您为 Android 开发并希望确保您的 IO 操作即使在清理 ViewModel 之后也能完全执行,请使用 WorkManager .它适用于需要保证即使应用程序退出系统也会运行它们的异步和可延迟任务。

关于android - 协程中的范围混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53472668/

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