一、MVVM 架构模式
1.1 核心定义
MVVM 是一种经典的软件架构模式,其核心组件定义如下:
- M (Model):数据层,负责管理应用的数据和业务逻辑。
- V (View):视图层,负责 UI 的展示。
- VM (ViewModel):UI 数据管理层,作为 View 和 Model 之间的桥梁。
1.2 主要思想
MVVM 的核心思想是 数据联动视图,即实现双向数据流。当数据发生变化时,UI 自动刷新;反之,用户在 UI 上的操作也能自动同步到数据模型中。
1.3 Android 官方解决方案
Android 平台为 MVVM 架构提供了强大的官方支持套件:
- DataBinding:提供更便捷的数据绑定方式。
- ViewModel:用于 UI 相关数据的存储和管理,其生命周期与 UI 控制器(如 Activity/Fragment)绑定,能有效避免内存泄漏。
- LiveData:一个拥有生命周期感知能力的数据观察者。它能确保只在 UI 处于活跃状态时更新数据,从而防止崩溃和内存泄漏。
【参考资料】
二、DataBinding 深度使用指南
2.1 基础配置
-
布局文件改造:
- 使用
<layout>标签包裹整个布局。 - 在
<layout>内部使用<data>标签声明需要绑定的变量。
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="userInfo" type="com.example.UserInfo" /> </data> <LinearLayout ...> <!-- UI elements --> </LinearLayout> </layout> - 使用
-
Activity/Fragment 中绑定:
- 通过
DataBindingUtil设置布局,并将 Model 和 Presenter(或 ViewModel)实例绑定到布局。
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setUserInfo(userInfo); - 通过
2.2 数据变化驱动 UI 刷新的方式
DataBinding 提供了三种主要方式来监听数据变化并自动刷新 UI:
-
BaseObservable:- 让数据模型继承
BaseObservable类。 - 在 setter 方法中调用
notifyPropertyChanged(BR.fieldName)来通知特定字段变更。
- 让数据模型继承
-
ObservableField:- 将字段包装成
ObservableField<T>、ObservableInt等类型。 - 当字段值改变时,会自动触发 UI 更新。
- 将字段包装成
-
ObservableCollection:- 适用于集合类型,如
ObservableArrayList、ObservableArrayMap。 - 集合内容变更时会通知观察者。
- 适用于集合类型,如
2.3 双向数据绑定
DataBinding 支持双向绑定,使得 UI 控件的值能直接回写到数据源。
-
语法:在表达式前加上
=号,即@={}。 -
示例:
此时,<EditText android:text="@={goods.name}" ... />EditText的文本内容与goods.name字段双向同步。
2.4 事件绑定
可以直接在 XML 中绑定各种事件处理器。
-
支持的事件:
android:onClickandroid:onLongClickandroid:afterTextChangedandroid:onTextChanged
2.5 调用工具类方法
可以在布局文件中直接调用工具类的静态方法对数据进行处理。
- 要求:被调用的方法必须位于一个静态类中。
-
示例:
<TextView android:text="@{StringUtils.toUpperCase(userInfo.name)}" ... />
2.6 表达式与运算符
DataBinding 支持在 XML 中使用简单的表达式和运算符。
-
空合并运算符 (
??):- 如果左边不为 null,则选择左边;否则选择右边。
-
示例:
<TextView android:text="@{user.name ?? user.password}" ... />
2.7 布局复用与数据共享
DataBinding 支持 <include> 和 <ViewStub>,并且可以方便地在包含的布局间共享数据。
-
示例:
这里通过<include layout="@layout/name_and_phone" bind:userInfo="@{userInfo}" />bind:前缀将userInfo对象传递给name_and_phone布局。
2.8 自定义属性行为 (BindingAdapter)
BindingAdapter 允许开发者自定义或修改 XML 属性的行为。
-
用途:
- 为自定义 View 添加新的可绑定属性。
- 改变现有属性(如
android:src)的加载逻辑(例如集成图片加载框架 Glide)。
【参考资料】
三、MVI 架构模式
3.1 核心思想
MVI(Model-View-Intent)是一种源自前端开发的思想,在 Flutter 等框架中也有体现,可以看作是 MVVM 的一种升级版或严格化版本。
MVI 最核心的特点是强调数据的单向流动,这使得数据流更加清晰、可预测,也更容易进行状态管理和测试。
3.2 工作流程
MVI 的工作流程遵循一个严格的循环:
- 用户操作:用户的交互(如点击按钮)被封装成一个 Intent(意图)。
- Model 处理:Model(通常是一个 Reducer 或类似组件)接收到 Intent 后,根据当前的 State 和 Intent 计算出一个新的、不可变的 State。
- View 刷新:View 观察到 State 的变化后,用新的 State 来刷新 UI。
这个 Intent -> State -> View 的单向循环确保了状态的唯一性和可追溯性。
【参考资料】
四、Android 架构模式演变
Android 应用架构经历了从简单到复杂的演变过程,以应对日益增长的项目复杂度和维护需求。
4.1 MVC (Model-View-Controller)
- 特点:早期 Web 开发常用模式。在 Android 中,Activity 既充当 View 又充当 Controller,导致代码臃肿、难以测试。
- 问题:关注点分离不彻底,Activity 责任过重。

MVC
4.2 MVP (Model-View-Presenter)
- 特点:将 Activity/Fragment 的逻辑抽离到一个独立的 Presenter 中。View 通过接口与 Presenter 通信,Presenter 负责业务逻辑并与 Model 交互。
- 优点:比 MVC 更清晰的关注点分离,Presenter 易于单元测试。
- 缺点:需要编写大量接口,存在内存泄漏风险(Presenter 持有 View 引用)。

MVP
4.3 MVVM (Model-View-ViewModel)
- 特点:引入了数据绑定和生命周期感知组件(如 LiveData),View 和 ViewModel 之间通过观察者模式进行通信,而非直接持有引用。
- 优点:进一步解耦,ViewModel 不依赖于具体的 View 实现,且能自动处理生命周期,有效避免内存泄漏。UI 逻辑更简洁。
- 缺点:学习曲线稍陡,过度使用数据绑定可能导致 XML 过于复杂。

MVVM
4.4 MVI (Model-View-Intent)
- 特点:强制单向数据流和不可变状态。所有状态变更都源于用户 Intent,状态是唯一的真相来源。
- 优点:状态管理极其清晰,非常适合复杂的状态驱动型 UI。易于实现撤销/重做、状态持久化等功能。
- 缺点:样板代码可能较多,对于简单场景可能显得过于重量级。

MVI
【补充问答】