如何使用 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
来表示任务是运行
如果您有任何疑问,请添加评论。
在我的应用程序中,我有这个流程:
我的片段中的 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
来表示任务是运行
如果您有任何疑问,请添加评论。