如何使用 liveData 处理错误

How to handle errors with liveData

在我的应用程序中,我有这个流程:

我的片段中的 ClickListender:

  search_button.setOnClickListener {
        if(search_input.text.isNullOrEmpty())
            Toast.makeText(activity, "Input Error", Toast.LENGTH_LONG).show()
        else
            viewModel.onSearchButtonClicked(search_input.text.toString())
    }

onSearchButtonClicked 里面 viewModel:

    fun onSearchButtonClicked(input: String) {
        coroutineScope.launch {
   repo.insertToDatabase(input)
        }
    }

insertToDatabase 里面 Repository:

   suspend fun insertToDatabase(string: String) {
        withContext(Dispatchers.IO) {
            val dataList =
                ExternalApi.retrofitCall.getData(string).await()
            if (dataList.intialDataResult < 1) {
                //show error
            } else {
                //all good
                database.myDataBase.insertAll(dataList)
            }
        }
    }

如果 intialDataResult 小于一,我需要显示错误消息。 我考虑过在我的存储库中创建初始值为 false 的 MutableLiveData 并通过 viewModel 从片段中监听,但这不是一个好方法,因为我无法将 LiveData 设置为 "false" 在我显示错误消息后再次出现。

我还尝试从 insertToDatabase 函数中 return bool 并决定是否显示错误,但没有成功。

有什么办法可以解决这个问题吗?

为什么不创建一个 LiveData 来管理您工作的结果状态?

创建一个class来存储工作结果why sealed class?

sealed class ResultState{
    object Success: ResultState() // this is object because I added no params
    data class Failure(val message: String): ResultState()
}

创建一个 LiveData 来报告这个结果

val stateLiveData = MutableLiveData<ResultState>()

做出insertToDatabase()return一个结果

suspend fun insertToDatabase(input: String): ResultState {
    return withContext<ResultState>(Dispatchers.IO) {

        val dataList =
            ExternalApi.retrofitCall.getData(string).await()
        if (dataList.intialDataResult < 1) {
            return@withContext ResultState.Failure("Reason of error...")
        } else {
            database.myDataBase.insertAll(dataList)
            return@withContext ResultState.Success
        }
    }
}

现在,将结果报告给UI

fun onSearchButtonClicked(input: String) {
    coroutineScope.launch {
        val resultState = repo.insertToDatabase(input)
        stateLiveData.value = resultState
    }
}

在UI,

viewModel.stateLiveData.observe(viewLifeCycleOwner, Observer { state ->

    when (state) {
        is ResultState.Success -> { /* show success in UI */ }
        is ResultState.Failure -> { /* show error in UI with state.message variable */ }
    }
})

同样,你可以在UI.

中添加一个ResultState.PROGRESS来表示任务是运行

如果您有任何疑问,请添加评论。