无法从ViewModel向用户显示协程错误消息
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法从ViewModel向用户显示协程错误消息相关的知识,希望对你有一定的参考价值。
当Retrofit API调用出现问题时,我正在尝试向用户显示错误消息。我正在使用Kotlin协程,Kodein和MVVM模式。鉴于在片段中未真正观察到MutableLiveData exceptionMessage,因此我无法在烤面包消息中显示错误消息(我猜想这与异步函数的性质有关,该异步函数通过API获取数据(暂停乐趣) ))。
ViewModel:
class BarcodeViewModel(
private val barcodeRepository: BarcodeRepository,
private val productRepository: ProductRepository
) : ViewModel() {
var exceptionMessage: MutableLiveData<String> = MutableLiveData()
private val handler = CoroutineExceptionHandler { _, exception ->
exceptionMessage.value = exception.localizedMessage
}
fun getBarcodeData(barcode: String) {
CoroutineScope(Dispatchers.Main).launch(handler) {
val currentArticle = barcodeRepository.getProductData(barcode)
for (article in currentArticle.products) {
val articleToAdd =
Product(...)
val articleDb = productRepository.getProduct(barcode)
if (articleDb.isEmpty()) {
productRepository.addProduct(articleToAdd)
exceptionMessage.value = ""
} else {
exceptionMessage.value = "Product already exists"
}
}
}
}
}
片段:
class ArticleAddFragment : Fragment(), LifecycleOwner, KodeinAware {
override val kodein: Kodein by kodein()
private val factory: BarcodeViewModelFactory by instance()
private lateinit var viewModel: BarcodeViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_article_add, container, false)
viewModel = ViewModelProviders.of(this, factory).get(BarcodeViewModel::class.java)
...
return view
}
private fun processResult(firebaseVisionBarcodes: List<FirebaseVisionBarcode>) {
if (firebaseVisionBarcodes.isNotEmpty()) {
for (item in firebaseVisionBarcodes) {
when (item.valueType) {
FirebaseVisionBarcode.TYPE_PRODUCT -> {
viewModel.getBarcodeData(item.rawValue!!)
viewModel.exceptionMessage.observe(viewLifecycleOwner, Observer {
it?.let {
if (!it.isBlank()) {
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
}
}
})
...
}
}
}
}
}
在吐司中显示错误消息的最明智的方法是什么?
答案
我建议使用密封类或枚举来更新和观察状态。
State.kt
sealed class State<T> {
class Loading<T> : State<T>()
data class Success<T>(val data: T) : State<T>()
data class Error<T>(val message: String) : State<T>()
companion object {
/**
* Returns [State.Loading] instance.
*/
fun <T> loading() = Loading<T>()
/**
* Returns [State.Success] instance.
* @param data Data to emit with status.
*/
fun <T> success(data: T) = Success(data)
/**
* Returns [State.Error] instance.
* @param message Description of failure.
*/
fun <T> error(message: String) = Error<T>(message)
}
}
这些类是通用的,因此您可以根据成功和失败来相应地放置数据。
以上是关于无法从ViewModel向用户显示协程错误消息的主要内容,如果未能解决你的问题,请参考以下文章