一文了解 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)使用。

相关推荐
小程故事多_808 小时前
从 Tokenizer 到 Next Token,穿透数据流,完整理解 Transformer 底层逻辑
android·深度学习·transformer
三少爷的鞋11 小时前
Android 协程实践:为什么不应将 `supervisorScope` 作为常规方案
android
承渊政道13 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从ChatGLM本地化到LoRA、PEFT的高级微调)
android·人工智能·pytorch·chatglm·本地化部署·大模型开发与微调
2601_9628857215 小时前
如何用 Python 判断一只股票“追涨”还是“抄底”更有效?
android·开发语言·python
素师良码15 小时前
第10篇:屏ESD Check内核逻辑驱动代码完整拆解
android
高晶15 小时前
Android 短信收发模块从零到实战:权限配置、界面设计、发送接收与兼容性适配全攻略
android·程序员
随遇丿而安15 小时前
第18周:ViewModel 基础功能 + 架构优化
android
问心无愧051318 小时前
[GXYCTF2019]Ping Ping Ping
android·笔记
事圆则缓18 小时前
Kotlin 异步与并发:从一次搜索请求走到状态流
android·开发语言·kotlin
帅得不敢出门19 小时前
Android Framework定制卸载确认窗口
android