我在我当前的 Android 应用程序中的多个 fragment 之间共享一个 ActivityScoped viewModel。
viewModel 使用 Coroutine Scope viewModelScope.launch{}
我的问题是 .launch{}
仅在拥有 ViewModel
之前有效onCleared()
方法被调用。
这是 ViewModel 范围内的协程应该如何工作的吗?
有没有一种方法可以用来“重置”viewModelScope,以便 .launch{} 在调用 onCleared() 方法之后工作?
这是我的代码::
fragment
RxSearchView.queryTextChangeEvents(search)
.doOnSubscribe {
compositeDisposable.add(it)
}
.throttleLast(300, TimeUnit.MILLISECONDS)
.debounce(300, TimeUnit.MILLISECONDS)
.map { event -> event.queryText().toString() }
.observeOn(AndroidSchedulers.mainThread())
.subscribe { charactersResponse ->
launch {
viewModel.search(charactersResponse.trim())
}
}
.
.
.
override fun onDetach() {
super.onDetach()
viewModel.cancelSearch()
compositeDisposable.clear()
}
查看型号
suspend fun search(searchString: String) {
cancelSearch()
if (TextUtils.isEmpty(searchString)) {
return
}
job = viewModelScope.launch {
repository.search(searchString)
}
}
fun cancelSearch() {
job?.cancelChildren()
}
.
.
.
override fun onCleared() {
super.onCleared()
repository.onCleared()
}
我究竟做错了什么?
更新
如果我将启动代码修改为此
job = GlobalScope.launch {
repository.search(searchString)
}
它解决了我的问题,但是这是实现我想要的结果的唯一方法吗?
我的印象是
GlobalScope
是“坏的”
最佳答案
following a cal to onCleared() my viewModelScoped cororoutine Launch stops executing
这是一个特性,而不是一个错误。
一旦
ViewModel
被清除,你不应该在 ViewModel
中做任何事情或任何LifecycleOwner
曾是。所有这些现在都已失效,不应再使用。however is this the only way to achieve my desired result?
正确的解决方案是去掉
ViewModel
中的代码。 .如果您期望某些后台工作超过 Activity 或 fragment 的生命周期,则该代码不属于 Activity/fragment 或其关联的 View 模型。它属于与您正在尝试做的工作具有匹配生命周期的事物。
关于android - 为什么 ViewModelScoped 协程在调用 ViewModel onCleared() 方法后无法使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58341983/