数据绑定与MVVM
数据绑定与MVVM:保留第四版正文机制,以所有者—状态—结果合同、事件轨迹和章专属故障完成可重放验收。
学习目标
- 能沿“数据绑定与MVVM”的用户事件解释Android组件、状态所有者、线程与销毁边界。
- 能围绕“理解 MVVM 架构模式,使用 Data Binding Library 消除样板代码,让 View 和 ViewModel 自动同步。”改出一个可运行结果,并用前后状态而非组件数量验收。
- 能在旋转、进程重建、拒权、离线或无效输入中选择适用反例,定位首个状态分叉。
- 能用构建指纹、用户操作、状态快照、原始日志和行为断言独立重放结论,并标明第四版机制与现代targetSdk政策的边界。
你的 UI 代码为什么越来越臃肿?
一个典型的 Activity:要在 onCreate 里 findViewById 拿几十个 View,要手动 setText 更新数据,要手动 setOnClickListener。数据一变更,要记住更新所有相关的 View。漏了一个——那就是 bug。
MVVM + Data Binding 解决了这个痛点:数据变,界面自动变。你只管更新 ViewModel 里的字段,XML 布局自动反映最新数据。
MVVM 三层
| 层 | 职责 | Kotlin 里是什么 |
|---|---|---|
| Model | 数据和业务逻辑 | Repository、Room Entity、网络请求 |
| View | UI 展示(XML + Activity/Fragment) | layout XML、Activity/Fragment |
| ViewModel | 为 View 准备数据、处理 UI 逻辑 | ViewModel 子类 + LiveData |
核心原则:ViewModel 不知道 View 的存在——它只暴露数据。View 观察 ViewModel 的数据变化,自动更新界面。
第 1 / 5 步 · ① 用户在 View 上操作(点了「添加」按钮)
点击播放,看一次「用户点一下」如何流到 ViewModel,再经 DataBinding 自动推回 View;可暂停、单步、拖进度逐帧观察。
Data Binding 实战
启用 Data Binding(build.gradle 加 dataBinding { enabled = true }),然后用 <layout> 包裹布局:
<layout xmlns:android="...">
<data>
<variable name="viewModel" type="com.example.MainViewModel" />
</data>
</layout>Activity 端只需一行绑定:
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this // 让 LiveData 自动感知生命周期
binding.viewModel = viewModelViewModel
class MainViewModel : ViewModel() {
private val _userName = MutableLiveData("张三")
val userName: LiveData<String> = _userName
fun onSaveClick() {
_userName.value = "李四" // 改数据 → View 自动更新!
}
}LiveData + Data Binding = 数据驱动 UI。ViewModel 只管改数据,XML 绑定自动反映——不用手动 findViewById + setText。
① 创建 ViewModel
继承 ViewModel(),内部用 MutableLiveData 存数据,对外暴露不可变的 LiveData。当数据变化时(如 _userName.value = "李四"),LiveData 自动通知所有观察者。
容易踩的坑
小结
- MVVM:Model(数据)、View(UI)、ViewModel(为View准备数据)——解耦可测试
- Data Binding 消除 findViewById 和手动 setText——数据变界面自动变
- LiveData + Data Binding = 生命周期安全的数据驱动 UI
- ViewBinding(轻量,只解决 findViewById)vs DataBinding(重量,支持表达式绑定)
- 列表场景用 ViewBinding,详情页用 DataBinding
练习
问题 1:“第19章 Data Binding and MVVM”覆盖哪些正式节点和项目主线?
问题 2:怎样建立本页最小可执行实验?
问题 3:为什么只在正常点击路径运行不能证明完成?
问题 4:怎样设计能推翻当前实现的反例?
问题 5:从第4版语境迁移到现代目标SDK时如何控制变量?
问题 6:本页达到独立交接标准需要什么?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- MVVM
Model-View-ViewModel 架构模式。Model 管数据,View 管界面展示,ViewModel 为 View 准备数据并处理 UI 逻辑。View 观察 ViewModel 的数据变化,自动更新界面。
- Data Binding
Android Jetpack 组件库的一部分。在 XML 布局中用
@{}表达式直接绑定 ViewModel 数据,运行时自动同步。消除 findViewById 和手动 UI 更新。
“数据绑定与MVVM”不使用未获授权的纸书正文;InformIT出版信息与授权电子版完整目录只用于确认第四版32章、269个正式目录节点和时代语境,第四版官方勘误用于识别工具链变更。下列中文解释、图示、交互、代码与练习均为独立教学重写,平台行为再以Android Developers的一手文档复核。
为什么“数据绑定与MVVM”必须回到可观察状态
“数据绑定与MVVM”的学习结果不是记住类名,而是能预测“理解 MVVM 架构模式,使用 Data Binding Library 消除样板代码,让 View 和 ViewModel 自动同步。”在一次输入、一次重建和一次失败中的不同状态,并指出哪条Android合同产生差异。
第四版机制逐项深读
19. Data Binding and MVVM
在“数据绑定与MVVM”中,验证“19. Data Binding and MVVM”用同一事件序列比较旋转前后状态和副作用次数;界面相同但重复写入仍是不正确。
Different Architectures: Why Bother?
在“数据绑定与MVVM”中,验证“Different Architectures: Why Bother?”用同一事件序列比较旋转前后状态和副作用次数;界面相同但重复写入仍是不正确。
MVVM View Models vs Jetpack ViewModels
在“数据绑定与MVVM”中,“MVVM View Models vs Jetpack ViewModels”的价值由依赖方向与可测试状态转换证明,而不是由类名是否含Model、View或Repository决定。
Creating BeatBox
在“数据绑定与MVVM”中,验证“Creating BeatBox”覆盖多指、取消、越界、旋转和辅助操作,比较模型框、Canvas输出与可访问性节点。
Implementing Simple Data Binding
在“数据绑定与MVVM”中,“Implementing Simple Data Binding”按事实、界面表示和用户事件拆责任;状态所有者不能持有已销毁View,界面也不能绕过边界直接改持久数据。
Importing Assets
在“数据绑定与MVVM”中,“Importing Assets”服务于“理解 MVVM 架构模式,使用 Data Binding Library 消除样板代码,让 View 和 ViewModel 自动同步。”;解释要落到用户事件、Android所有者、状态变化、线程和可观察结果,并给出一个会推翻实现的反例。
Accessing Assets
在“数据绑定与MVVM”中,“Accessing Assets”若依赖第四版时期API,应分开说明原书机制与现代平台政策,并用Android官方文档核对迁移边界。
Wiring Up Assets for Use
在“数据绑定与MVVM”中,“Wiring Up Assets for Use”服务于“理解 MVVM 架构模式,使用 Data Binding Library 消除样板代码,让 View 和 ViewModel 自动同步。”;解释要落到用户事件、Android所有者、状态变化、线程和可观察结果,并给出一个会推翻实现的反例。
Binding to Data
在“数据绑定与MVVM”中,“Binding to Data”服务于“理解 MVVM 架构模式,使用 Data Binding Library 消除样板代码,让 View 和 ViewModel 自动同步。”;解释要落到用户事件、Android所有者、状态变化、线程和可观察结果,并给出一个会推翻实现的反例。
For the More Curious: More About Data Binding
在“数据绑定与MVVM”中,验证“For the More Curious: More About Data Binding”用同一事件序列比较旋转前后状态和副作用次数;界面相同但重复写入仍是不正确。
For the More Curious: LiveData and Data Binding
在“数据绑定与MVVM”中,分析“For the More Curious: LiveData and Data Binding”要画出事件进入、状态归约、数据源写入和UI重绘四条边,并指出配置变化时谁被重建。
“数据绑定与MVVM”验收回顾
“数据绑定与MVVM”只有在构建指纹、用户操作、状态快照、原始日志和行为断言能够从相同基线再次得到相同断言时才通过;第四版机制与现代平台政策分别记录,不用新API名称掩盖旧行为。
← 上一页:Android辅助功能 · 下一页:音频播放与单元测试 →
章专属可重放状态实验
先预测“加载资产、绑定列表、点击声音与旋转”发生后,BeatBoxViewModel、SoundViewModel 与 Binding应怎样改变资产列表、显示文本、用户命令、观察值和 View 状态;再操作三个实验。第四版示例与当前 Android 政策分别记录,实验不把新 API 名称倒填为原书内容。
实验一:所有者—状态—结果合同
选择任一正式目录节点和正常/边界场景,检查它是否真的进入本章状态合同。目录标题只有同时出现在解释、可视状态和交付证据中才算覆盖。
Owner · state · observable result
数据绑定与MVVM:状态合同
区分 MVVM 表示状态、Jetpack ViewModel 寿命与 Data Binding 更新
验证场景
第四版正式目录节点
data-binding-mvvm · 正常任务
19. Data Binding and MVVM:固定 SDK、设备配置和初始状态,触发“加载资产、绑定列表、点击声音与旋转”
冻结入口:19. Data Binding and MVVM
记录BeatBoxViewModel、SoundViewModel 与 Binding的初始资产列表、显示文本、用户命令、观察值和 View 状态
观察:实例 ID、绑定求值、资产状态、点击事件和泄漏检查中的“19. Data Binding and MVVM”轨迹
预期:由BeatBoxViewModel、SoundViewModel 与 Binding提交资产列表、显示文本、用户命令、观察值和 View 状态,并持续满足“状态所有者不持有已销毁 View,Binding 只渲染可观察事实”
实验二:事件与生命周期轨迹
沿五次转换逐步执行“加载资产、绑定列表、点击声音与旋转”。每一步只允许BeatBoxViewModel、SoundViewModel 与 Binding按职责提交状态,并持续核对“状态所有者不持有已销毁 View,Binding 只渲染可观察事实”。
Deterministic event replay
数据绑定与MVVM:事件轨迹
不变量:状态所有者不持有已销毁 View,Binding 只渲染可观察事实
交付证据:实例 ID、绑定求值、资产状态、点击事件和泄漏检查
实验三:章专属反例与同输入恢复
注入“ViewModel 保存 Activity 或 Binding 引用,旋转后泄漏旧界面”,保存第一个偏离点;撤销后以完全相同的 SDK、设备状态和用户事件重放。只有实例 ID、绑定求值、资产状态、点击事件和泄漏检查一起恢复才算修复。
Fault · cancel · restore
数据绑定与MVVM:反例与恢复
故障:ViewModel 保存 Activity 或 Binding 引用,旋转后泄漏旧界面
第 1 次使用相同 SDK、设备配置、初始状态与用户事件
保持正常输入不变,仅注入“ViewModel 保存 Activity 或 Binding 引用,旋转后泄漏旧界面”
状态所有者不持有已销毁 View,Binding 只渲染可观察事实
实例 ID、绑定求值、资产状态、点击事件和泄漏检查