我目前正在开发一个利用 MVI(模型-视图-意图)架构的 Android 应用程序。在我的 ViewModel 中,我使用 MutableStateFlow 来管理 UI 状态。我想优化我的代码,以防止在检查 ViewModel 状态中的响应请求时进行重复工作。
我已经实现了以下方法来处理 ViewModel 中的响应请求:
@HiltViewModel
class ListViewModel @Inject constructor(private val repository: ListRepository) : ViewModel() {
val intentChannel = Channel<ListIntent>()
private val _state = MutableStateFlow<ListState>(ListState.Idle)
val state: StateFlow<ListState> get() = _state
init {
handleIntents()
}
private fun handleIntents() = viewModelScope.launch {
intentChannel.consumeAsFlow().collect { intent ->
when (intent) {
is ListIntent.LoadFiltersLetters -> fetchingFiltersList()
is ListIntent.LoadRandom -> fetchingRandomFood()
is ListIntent.LoadCategoriesList -> fetchingCategoriesList()
is ListIntent.LoadFoods -> fetchingFoodsList(intent.letter)
is ListIntent.LoadSearchFoods -> fetchingSearchFood(intent.search)
is ListIntent.LoadFoodByCategory -> fetchingFoodsByCategory(intent.category)
}
}
}
private fun fetchingFoodsByCategory(category: String) = viewModelScope.launch {
val response = repository.foodByCategory(category)
_state.emit(ListState.LoadingFoods)
when (response.code()) {
in 200..202 -> {
_state.value = if (response.body()!!.meals != null) {
ListState.FoodsList(response.body()!!.meals!!)
} else {
ListState.Empty
}
}
in 400..499 -> {
_state.emit(ListState.Error(""))
}
in 500..599 -> {
_state.emit(ListState.Error(""))
}
}
}
private fun fetchingSearchFood(search: String) = viewModelScope.launch {
val response = repository.searchFood(search)
_state.emit(ListState.LoadingFoods)
when (response.code()) {
in 200..202 -> {
_state.value = if (response.body()!!.meals != null) {
ListState.FoodsList(response.body()!!.meals!!)
} else {
ListState.Empty
}
}
in 400..499 -> {
_state.emit(ListState.Error(""))
}
in 500..599 -> {
_state.emit(ListState.Error(""))
}
}
}
private fun fetchingFoodsList(letter: String) = viewModelScope.launch {
val response = repository.foodsList(letter)
_state.emit(ListState.LoadingFoods)
when (response.code()) {
in 200..202 -> {
_state.value = if (response.body()!!.meals != null) {
ListState.FoodsList(response.body()!!.meals!!)
} else {
ListState.Empty
}
}
in 400..499 -> {
_state.emit(ListState.Error(""))
}
in 500..599 -> {
_state.emit(ListState.Error(""))
}
}
}
private fun fetchingCategoriesList() = viewModelScope.launch {
val response = repository.categoriesList()
_state.emit(ListState.LoadingCategory)
when (response.code()) {
in 200..202 -> {
_state.emit(ListState.CategoriesList(response.body()!!.categories))
}
in 400..499 -> {
_state.emit(ListState.Error(""))
}
in 500..599 -> {
_state.emit(ListState.Error(""))
}
}
}
private suspend fun fetchingRandomFood() {
val response = repository.randomFood()
when (response.code()) {
in 200..202 -> {
_state.emit(ListState.RandomFood(response.body()?.meals?.get(0)))
}
in 400..499 -> {
_state.emit(ListState.Error(""))
}
in 500..599 -> {
_state.emit(ListState.Error(""))
}
}
}
private suspend fun fetchingFiltersList() {
val list = listOf('A'..'Z').flatten().toMutableList()
_state.emit(ListState.FilterLetters(list))
}
}
when (response.code()) {
in 200..202 -> {
}
in 400..499 -> {
}
in 500..599 -> {
}
}
但是,我发现自己为不同的功能重复类似的代码,这不是最佳的 我听说使用协程和流可以帮助避免这种重复。您能否指导我如何使用协程和流程改进此代码,以最大限度地减少冗余,同时有效处理响应请求?您的见解和代码示例将不胜感激。谢谢!
我使用mvi架构
when (response.code()) {
in 200..202 -> {
}
in 400..499 -> {
}
in 500..599 -> {
}
}
我想在 ViewModel 中执行此操作,而不是在存储库中,并避免重复代码
将所有这些代码传输到存储库,只需更改视图模型中的状态流值并在片段/活动中观察它。 创建一个具有 int 值的枚举类来表示这些方法。只需将枚举类型和查询字符串发送到存储库即可。根据这些枚举类型进行切换,并调用食物的数据库方法并相应地返回列表。希望你理解。