【问题标题】:Android Livedata Observer Coroutine KotlinAndroid Livedata Observer 协程 Kotlin
【发布时间】:2019-10-10 15:26:08
【问题描述】:

是否可以在观察者内部有一个协程来更新 UI?

例如:

Viewmodel.data.observer(this, Observer{ coroutinescope })

【问题讨论】:

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


    【解决方案1】:

    您可以从Observer 回调中运行您想要的任何代码。但是稍后启动一个更新 UI 的协程并不是一个好主意,因为当协程完成时,UI 可能会被破坏,这可能会导致抛出异常并导致您的应用崩溃。

    只需直接从Observercallback 运行 UI 更新代码。

    viewModel.data.observe(this, Observer {
        // Update the UI here directly
    })
    

    这样您在更新 UI 时就知道它是活动的,因为 LiveData 考虑了 this 的生命周期。

    如果你想在回调的同时启动一些协程,最好在你的viewModel 中使用viewModelScope

    // This triggers the above code
    data.value = "foo"
    
    // Now also launch a network request with a coroutine
    viewModelScope.launch { 
        val moreData = api.doNetworkRequest()
        // Set the result in another LiveData
        otherLiveData.value = moreData
    }
    

    请注意,您必须向build.gradle 添加依赖项才能使用viewModelScope

    dependencies {
        implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
    }
    

    【讨论】:

    • 如果我们希望协程完成并 LiveData 交付结果 - 在我们对 UI 执行任何其他操作之前怎么办?
    【解决方案2】:

    是的,这是可能的。您可以启动 GlobalScope 协程,当您需要更新 UI 时,您应该在活动中使用!!.runOnUiThread

    这里是一个示例。

    viewModel.phoneNumber.observe(this, Observer { phoneNumber ->
            GlobalScope.launch {
                delay(1000L) //Wait a moment (1 Second)
                activity!!.runOnUiThread {
                    binding.textviewPhoneLabel.edittextName.setText(phoneNumber)
                }
            }
        })
    

    【讨论】:

    • 听起来像是伪装的内存泄漏
    • 不是,@EpicPandaForce 这么高效,这只是一个不好的做法,但是,如果他需要,他应该使用它
    • 不,这是内存泄漏。无论封闭的 Activity 如何,GlobalScope 都会运行,并且不会在 Activity 死亡时取消,因此如果您在电话号码更改后导航回 1 秒,activity!! 可能会爆炸
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多