MVI 在 Android 中的实现方案

23 阅读2分钟

一、前言

在前面的文章中,从整体上介绍了 Android 设计架构的跃迁

对于设计架构,我的理解是需要针对不同的场景进行选择,不一定说 MVP 就很差,用 MVI 就很好。甚至在简单场景下,MVC 也能很好完成业务需求。

避免陷入设计模式的怪圈,我们必须考虑到当下的业务场景,选择合适的设计模式。

二、简单设计一个 MVI 架构

来看一个简单的实例,从示例中体会 MVI 设计架构的精髓。(示例来源于Android develop

// State
data class LoginUiState(
    val isLoading: Boolean = false,
    val errorMessage: String? = null,
    val isUserLoggedIn: Boolean = false
)

// ViewModel
class LoginViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(LoginUiState())
    val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
    /* ... */
}


// Activity
class LoginActivity : AppCompatActivity() {
    private val viewModel: LoginViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect { uiState ->
                    if (uiState.isUserLoggedIn) {
                        // Navigate to the Home screen.
                    }
                }
            }
        }
    }
}

整体的流程是这样的:

  1. 用户 Intent 向下传递,ViewModel 触发事件发起网络请求
  2. 页面的状态抽象成一个 State 进行统一管理,State 是不可变的,可以使用 copy 更新一个新的 State
  3. 在 UI Layer 收集 flow 发出的数据

在示例中没有体现的是,通常用户的行为可以封装成一系列的 Intent,在 ViewModel 中分发不同的 Intent,处理不同的业务逻辑。

二、MVI 设计理念

在 MVI 之前,主流的设计模式是 MVVM,为什么又推出了 MVI 呢?相比于 MVVM,MVI 的优点在哪里呢?它又解决了 MVVM 的哪些痛点问题?

1、MVVM 痛点问题

在一个复杂的页面,MVVM 可能具有的问题:

  1. LiveData 过多,一个 UI 状态可能是多个 LiveData 共同作用
  2. LiveData 存在数据倒灌,无法更好处理事件

2、MVI 设计原则

MVI 具有如下的特点:

  1. 集中 State 管理,State 不可变
  2. 单项数据流,事件向下,State 向上

参考文章:juejin.cn/post/702262…