【问题标题】:Specify an existing LiveData object for the liveData kotlin builder function为 liveData kotlin builder 函数指定一个现有的 LiveData 对象
【发布时间】:2022-01-10 13:31:51
【问题描述】:

例如,我们可以使用liveData 构建器函数创建一个LiveData 对象:

var liveData: LiveData<String> = liveData(Dispatchers.IO) {
    delay(1000)
    emit ("hello")

    delay(1000)
    emit ("world")
}

这在ViewModel 中很有用,我创建了一个LiveData 对象,它在一行中接收来自异步重载函数的多个数据值。

但是,如果我已经有一个MutableLiveData 对象并且只想在其中发布值,而不创建新的LiveData 对象怎么办?我该怎么做?

我需要一种方法将多个值异步发送到 MutableLiveData 范围内的现有 MutableLiveData 对象中,以便在清除 ViewModel 时自动完成所有正在运行的任务。

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    您可以在从viewModelScope 启动的协程中发布到 MutableLiveData。

    private val myMutableLiveData = MutableLiveData<String>()
    
    fun someFun() {
        viewModelScope.launch {
            myMutableLiveData.value = “Hello”
            delay(500L)
            myMutableLiveData.value = “World”
    
            myMutableLiveData.value = someSuspendFunctionRetriever()
    
            val result = withContext(Dispatchers.IO) {
                someBlockingCallRetriever()
            }
            myMutableLiveData.value = result
    
            // or use post() when not on Main dispatcher:
            withContext(Dispatchers.IO) {
                val result = someBlockingCallRetriever()
                myMutableLiveData.post(result)
            }
        }
    }
    

    【讨论】:

    • 谢谢,我也找到了类似的方法。也可以直接在launch builder 函数中指定上下文:viewModelScope.launch(Dispatchers.IO) {liveData.postValue("")}
    • Android 库中的许多函数都假定您是从主线程调用的,因此通常将协程保留在主调度程序上是惯例。阻塞函数比较少见,所以它们通常只是协程中的一小部分,所以它们可以被包裹在withContext 中。一个例外是一个非常短的协程,它不必与任何主函数或对象交互。
    • 但是在非主线程中运行协程到底有什么问题呢?卸载的主线程越多越好,不是吗?
    • 这绝不是一个规则,但我认为在 Main 上保留长协程并使用 .value = 会更干净,因为 Android 中的很多类都没有 post 变体所以你经常有无论如何都要在协程中的某个地方使用主调度程序。这也确保了您的所有 ViewModel 属性仅在主线程上被触及,因此非协程代码也使用这些属性不会出现并发问题。它使您的协程与生命周期函数相匹配,几乎所有代码都从主线程调用。
    • 在阅读了官方文档后,我发现阅读协程设计负责人的这些文章有助于使我的概念得到点击。但这些都不是 Android 特定的。 OneTwo还有一个Android CodeLab,教一些使用协程的基础知识:developer.android.com/codelabs/kotlin-coroutines#0
    猜你喜欢
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多