【问题标题】:Should I pass viewModelScope.coroutineContext to liveData builder function?我应该将 viewModelScope.coroutineContext 传递给 liveData 构建器函数吗?
【发布时间】:2019-07-22 16:45:21
【问题描述】:

viewModelScope 用于将协程生命周期绑定到 ViewModel 生命周期。 liveData 构建器创建一个运行协程的 LiveData,其生命周期绑定到 LiveData 状态,因此,当 LiveData 不活动时,协程在超时后取消。由于超时,协程不会在配置更改时取消。

如果我通过liveDataViewModel 中创建LiveData 构建器,并观察Activity 中的LiveDataLiveData 生命周期已经绑定到Activity 生命周期。我还应该将viewModelScope.coroutineContext 传递给liveData 构建器吗?我认为我不应该这样做,但在其中一个 Android 文档samples 中它通过了:

class MyViewModel: ViewModel() {
    private val userId: LiveData<String> = MutableLiveData()
    val user = userId.switchMap { id ->
        liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) {
            emit(database.loadUserById(id))
        }
    }
}

【问题讨论】:

  • 似乎只能将实时数据传递给处于“STARTED”或“RESUMED”状态的LifecycleOwner。因此,在viewModelScope 中运行 couroutine 时,如果观察者在这些状态之外,则可能不会收到发出的数据。
  • 您是否打算使用viewModelScope?你的问题有点复杂。为什么不使用 LiveData 范围 (lifecycle-livedata-ktx)
  • 你将如何触发用户liveData

标签: android android-architecture-components android-livedata android-viewmodel kotlin-coroutines


【解决方案1】:

问: LiveData 生命周期已经绑定到 Activity 生命周期。我应该将viewModelScope 传递给liveData 构建器吗?

在简单的情况下,当一个 Activity 只有一个 ViewModel 时,Activity 生命周期与 ViewModel 生命周期相同,并且无论您将“viewModelScope”传递给 @987654331,它都不应该改变任何东西@builder 与否。但在更复杂的情况下,例如片段之间的ViewModelis sharedFragment 生命周期可能与共享的ViewModel 生命周期不匹配,在这种情况下,在 'viewModelScope.coroutineContext' 中启动协程是有意义的.


因此,您可以使用 viewModelScope 为您的 liveData 构建器提供上下文。

为什么?

根据official doc为每个定义一个ViewModelScope ViewModel 在您的应用程序中。在这个范围内启动的任何协程都是 如果ViewModel被清除自动取消。

因此,它有助于在您的LiveData取消当前工作,因为它现在已绑定到您的ViewModelScope

此外,viewModelScope 在您为布局计算一些数据 时会很有帮助,您应该将工作范围限定为ViewModel,这样如果ViewModel 被清除,则工作是自动取消以避免消耗资源。

【讨论】:

  • 能否请您稍微解释一下您的答案:“尽管您将 LiveData 绑定到 Activity 生命周期,但您从中观察 LiveData 的 ViewModel 也绑定到 Same Activity 生命周期。”。如果协程的生命周期已经绑定到 Activity,当 Activity 被销毁时,协程就会被取消。如果我另外将 viewModelScope 上下文传递给协程,它会发生什么变化?
  • 所以,如果我share a ViewModel between fragments,协程生命周期应该绑定到那个ViewModel,是的,这是有道理的。当 ViewModel 生命周期与 LifecycleOwner 生命周期不同时,我没有考虑这种情况。这是我要求的,你能更新你的答案吗?那我就可以接受了。
  • ~"取消当前作业"。谁应该这样做?
  • 如果您将视图模型范围传递给实时数据构建器,那么一旦视图模型范围被取消,它就会被取消。在我们的例子中,一旦视图模型达到清晰状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 2022-01-16
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2015-09-24
相关资源
最近更新 更多