如何使用挂起方法初始化视图中的字段模型



如果我需要调用暂停函数来获取值,如何在视图模型中初始化字段?

我有一个从数据库返回值的挂起函数。

suspend fun fetchProduct(): Product

当我创建视图模型时,我必须在此字段中获取产品

private val selectedProduct: Product 

我尝试这样做,但它不起作用,因为我在协程之外调用此方法

private val selectedProduct: Product = repository.fetchProduct()

您无法按照描述的方式初始化字段。suspend函数必须从协程或其他suspend函数调用。要启动协程,有几个构建器:CoroutineScope.launchCoroutineScope.asyncrunBlocking。不建议在生产代码中使用后者。还有一些构建器 -liveDataflow- 可用于初始化字段。对于您的情况,我建议使用LiveDataFlow来观察字段初始化。使用liveData生成器函数调用suspend函数的示例代码:

val selectedProduct: LiveData<Product> = liveData {
val product = repository.fetchProduct()
emit(product)
}

如果你想在初始化这个字段后在UI中做一些事情,你需要观察它。在ActivityFragment中,它将如下所示:

// 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)

对于liveData,请使用androidx.lifecycle:lifecycle-livedata-ktx:2.4.0或更高版本。

由于fetchProduct()是一个挂起函数,因此必须在协程作用域内调用它。

对于您的情况,我会建议以下选项:

  1. selectedProduct定义为可为空,并在ViewModel中将其初始化为null
class AnyViewModel : ViewModel {
private val selectedProduct: Product? = null

init {
viewModelScope.launch {
selectedProduct = repository.fetchProduct()
}
}
}
  1. 将选定产品定义为lateinit var并执行与上述相同的操作;

就个人而言,我更喜欢第一个原因,因为我觉得我可以更好地控制变量是否定义的事实。

您需要在协程范围内运行函数才能获取值。

如果你在ViewModel()类中,你可以安全地使用viewModelScope。

private lateinit var selectedProduct:Product
fun initialize(){
viewModelScope.launch {
selectedProduct = repository.fetchProduct()
}
}

相关内容

  • 没有找到相关文章

最新更新