You can't initialize a field in the way you described. suspend
function must be called from a coroutine or another suspend
function. To launch a coroutine there are a couple of builders for that: CoroutineScope.launch
, CoroutineScope.async
, runBlocking
. The latter is not recommended to use in production code. There are also a couple of builders - liveData
, flow
- which can be used to initialize the field. For your case I would recommend to use a LiveData
or Flow
to observe the field initialization. The sample code, which uses the liveData
builder function to call a suspend
function:
val selectedProduct: LiveData<Product> = liveData {
val product = repository.fetchProduct()
emit(product)
}
And if you want to do something in UI after this field is initialized you need to observe it. In Activity
or Fragment
it will look something like the following:
// Create the observer which updates the UI.
val productObserver = Observer<Product> { product ->
// Update the UI, in this case, a TextView.
productNameTextView.text = product.name
}
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
viewModel.selectedProduct.observe(this, productObserver)
For liveData
, use androidx.lifecycle:lifecycle-livedata-ktx:2.4.0
or higher.