DataBinding 是 Jetpack 中实现声明式 UI 绑定的库,它将数据对象直接绑定到布局文件,在编译期生成绑定类,消除 findViewById 样板代码,并支持双向绑定与自定义绑定适配器。
一、基础使用
Step 1:启用 DataBinding
// app/build.gradle |
Step 2:布局声明
<layout xmlns:android="http://schemas.android.com/apk/res/android"> |
Step 3:Activity 中使用
class MainActivity : AppCompatActivity() { |
编译期自动生成 ActivityMainBinding 类,包含所有视图引用(免去 findViewById)和数据绑定逻辑。
二、BindingAdapter:自定义属性
|
布局中直接使用:app:imageUrl="@{user.avatar}",无需在 Java/Kotlin 代码中手动调用图片加载库。
三、Observable 与双向绑定
ObservableField 让单个字段变更自动通知 UI:
class User { |
双向绑定(@={})在 EditText 等可编辑控件上同步数据变化。结合 InverseBindingAdapter 可自定义转换逻辑。
四、DataBinding vs ViewBinding vs findViewById
| 特性 | DataBinding | ViewBinding | findViewById |
|---|---|---|---|
| 布局表达式 | 支持 | 不支持 | 不支持 |
| 双向绑定 | 支持 | 不支持 | 不支持 |
| 编译时安全 | 支持 | 支持 | 不支持 |
| 生成方式 | 注解处理 + 代码生成 | 代码生成 | 运行时反射 |
| 构建速度 | 较慢 | 快 | 最快(但低效) |
| 适用场景 | MVVM 中需要数据驱动 UI | 仅需 View 引用 | 仅原型 / 已废弃 |
面试常考问题
Q1:DataBinding 的核心原理?
DataBinding 在编译时扫描 <layout> 标签包裹的 XML 文件,通过 annotation processor 生成 Binding 类(继承自 ViewDataBinding)。该类持有所有 View 引用,并在 executeBindings() 中执行布局表达式。数据变更通过 Observable 接口回调触发绑定重新执行。源码入口:androidx.databinding.DataBindingUtil。
Q2:@BindingAdapter 的 override 参数有何作用?
当多个 @BindingAdapter 注解了相同的属性名时,需要指定 requireAll = false 表示不必所有适配器都执行,以及 override = true 来决定优先级覆盖策略。这用于在全局注册多个同属性适配器时的冲突解决。
Q3:DataBinding 如何避免 null 安全导致的崩溃?
DataBinding 生成的代码在 setter 调用前自动进行 null 检查。例如 android:text="@{user.name}" 生成代码等价于 if (user != null && user.getName() != null) textView.setText(...)。此外 @BindingAdapter 的参数默认 nullable,可通过 @NonNull 注解覆盖。







