Reputation: 509
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
Reputation: 1
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
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 Observer
callback.
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