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

相关推荐
HLC++13 小时前
Linux的进程间通信
android·linux·服务器
爱笑鱼16 小时前
Binder(二):AIDL 生成的 Proxy、Stub 和 Parcel 到底在做什么?
android
爱笑鱼17 小时前
Binder(一):一次方法调用,究竟怎样跨进程执行?
android
壮哥_icon18 小时前
【Android 系统开发】使用 BAT 脚本高效自动化管理 /system/priv-app/ 系统应用(安装与卸载)
android·运维·自动化
用户693717500138419 小时前
Claude Code终端日志Token占用实测:一个过滤器砍掉60%-90%
android·前端·后端
蝉蜕日记19 小时前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
吐了啊取名字太难19 小时前
美颜系统AI修图本地跑并支持Mac、win、安卓、iOS不卡顿
android·人工智能·windows·数码相机·mac·ai编程
阿pin21 小时前
Android随笔-Retrofit
android·retrofit
想取一个与众不同的名字好难21 小时前
安卓自定义颜色选择器
android
我命由我1234521 小时前
Android 开发问题:java.lang.NoSuchMethodError:No virtual method readAllBytes()
android·java·java-ee·kotlin·android studio·android-studio·android runtime