android - 为什么 ViewModelScoped 协程在调用 ViewModel onCleared() 方法后无法使用

标签 android dagger-2 kotlin-coroutines android-viewmodel

我在我当前的 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/

相关文章:

android - 使用 kapt 时,Dagger 会跳过 Google 服务模块的工厂生成

android - 为更新的 bool 值添加流程

java - 迁移到 AndroidX -“程序类型已存在 : android. support.v4.media.MediaBrowserCompat

java - 自定义 Android 适配器从不显示数据

java - 如何仅在应用程序启动时调用方法?请查看详情

java - Dagger2 组件注入(inject)多个 Activity

android - 使用 Ant 构建已签名和未签名的版本

android - 将 Activity ViewModel 注入(inject) fragment ViewModel

kotlin - 我如何在惯用的Kotlin中 “wrap”这个不太好的-“by lazy”结果缓存函数调用?

android - Kotlin 协程为什么要在协程范围中使用上下文?