一文了解 Android MVI 架构

Android 的 ​MVI(Model-View-Intent)​​ 是一种响应式架构模式,强调单向数据流和状态管理,适合复杂 UI 交互的应用。以下是其核心要点:


1. 核心组件

  • Model (状态)​
    用不可变数据类表示应用状态(如 data class UiState),确保状态变更可预测。
  • View (UI)​
    Activity/Fragment 只负责渲染状态和发送用户意图(Intent),不处理逻辑。
  • Intent (用户意图)​
    用户操作(如按钮点击)被封装为 Intent(如 Sealed class UserIntent),传递给 ViewModel 处理。

2. 数据流(单向)​

  1. 用户触发 Intent
    View 将 UserIntent 发送给 ViewModel。
  2. ViewModel 处理
    根据 Intent 执行业务逻辑(如调用 Repository),生成新状态。
  3. 状态更新
    ViewModel 将新状态 UiState 推送给 View。
  4. UI 渲染
    View 根据最新状态自动更新界面。

3. 关键特点

  • 单一数据源:所有状态集中管理,避免数据不一致。
  • 不可变状态:状态不可修改,只能通过创建新实例更新。
  • 响应式编程:常用 Kotlin Flow 或 RxJava 实现数据流。
  • 纯函数式处理:Intent 到状态的转换是纯函数,易于测试。

4. 代码示例

状态定义

kotlin 复制代码
data class MainUiState(
    val isLoading: Boolean = false,
    val data: List<String> = emptyList(),
    val error: String? = null
)

用户意图

kotlin 复制代码
sealed class MainIntent {
    object LoadData : MainIntent()
    data class DeleteItem(val id: String) : MainIntent()
}

ViewModel 处理

kotlin 复制代码
class MainViewModel : ViewModel() {
    private val _state = MutableStateFlow(MainUiState())
    val state: StateFlow<MainUiState> = _state.asStateFlow()

    fun processIntent(intent: MainIntent) {
        when (intent) {
            is MainIntent.LoadData -> loadData()
            is MainIntent.DeleteItem -> deleteItem(intent.id)
        }
    }

    private fun loadData() {
        viewModelScope.launch {
            _state.update { it.copy(isLoading = true) }
            repository.getData()
                .onSuccess { _state.update { it.copy(data = it, isLoading = false) } }
                .onFailure { _state.update { it.copy(error = "加载失败", isLoading = false) } }
        }
    }
}

View 绑定

kotlin 复制代码
// Activity/Fragment 中观察状态
viewModel.state.collect { state ->
    if (state.isLoading) showLoading()
    state.data?.let { updateList(it) }
    state.error?.let { showError(it) }
}

// 发送 Intent
button.setOnClickListener { 
    viewModel.processIntent(MainIntent.LoadData) 
}

5. 对比其他架构

  • MVP:MVI 用状态驱动 UI,避免 MVP 中 View 接口的冗余。
  • MVVM:MVI 明确约束状态管理,MVVM 的 LiveData 更松散。
  • Redux:类似单向数据流,但 MVI 更轻量,适合 Android 场景。

6. 优缺点

  • 优点​:

    • 状态管理清晰,适合复杂 UI。
    • 易于调试(状态变化可追溯)。
    • 天然支持 Jetpack Compose。
  • 缺点​:

    • 模板代码较多(需定义大量状态类)。
    • 学习成本较高(需熟悉响应式编程)。

适用场景

  • 需要严格状态管理的页面(如表单、多步骤操作)。
  • 与 Jetpack Compose 结合时效果更佳。

通过 MVI,可以构建高可维护性、可测试性的 Android 应用。推荐结合 Kotlin Flow 和 Jetpack 组件(如 ViewModel、StateFlow)使用。

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui