Hoang Trung Nguyen
Hoang Trung Nguyen

Reputation: 509

Android Livedata Observer Coroutine Kotlin

Is it possible to have a co-routine inside an observer to update the UI?

For Example:

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

Upvotes: 3

Views: 4320

Answers (2)

Yes, it's possible. You can launch a GlobalScope coroutine and when you need update the UI you should be that in activity!!.runOnUiThread

Here a sample.

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

Upvotes: -3

Enselic
Enselic

Reputation: 4902

You can run any code you want from the Observer callback. But it would not be a good idea to launch a coroutine that updates the UI later, because when the coroutine is complete, the UI might be destroyed, which can cause exceptions to be thrown and crash your app.

Just run the UI update code directly from the Observercallback.

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

That way you know that UI is alive when you update it, since LiveData takes the lifecycle of this into account.

If you want to launch some coroutine at the same time as the callback, it would be better to do it within your viewModel using 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
}

Note that you must add a dependency to build.gradle in order to use viewModelScope:

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

Upvotes: 6

Related Questions