一、前言
在前面的文章中,从整体上介绍了 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.
}
}
}
}
}
}
整体的流程是这样的:
- 用户 Intent 向下传递,ViewModel 触发事件发起网络请求
- 页面的状态抽象成一个 State 进行统一管理,State 是不可变的,可以使用 copy 更新一个新的 State
- 在 UI Layer 收集 flow 发出的数据
在示例中没有体现的是,通常用户的行为可以封装成一系列的 Intent,在 ViewModel 中分发不同的 Intent,处理不同的业务逻辑。
二、MVI 设计理念
在 MVI 之前,主流的设计模式是 MVVM,为什么又推出了 MVI 呢?相比于 MVVM,MVI 的优点在哪里呢?它又解决了 MVVM 的哪些痛点问题?
1、MVVM 痛点问题
在一个复杂的页面,MVVM 可能具有的问题:
- LiveData 过多,一个 UI 状态可能是多个 LiveData 共同作用
- LiveData 存在数据倒灌,无法更好处理事件
2、MVI 设计原则
MVI 具有如下的特点:
- 集中 State 管理,State 不可变
- 单项数据流,事件向下,State 向上