###开发阶段 #####UserModel.java
1 |
|
#####activity_main.xml
在xml中使用”@{}”标识符
1 |
|
#####MainActivity.java
1 |
|
###编译阶段
####1.Databinding会自动解析识别xml中的”@{}”标识符,并在以下目录生成2个xml文件
1.build/intermediates/data-binding-layout-out/activity_main.xml 2.build/intermediates/data-binding-info/debug/activity_main-layout.xml
######activity_main.xml
带“@{}”的xml文件是android系统无法识别的,为了向后兼容,需要在编译期统一转换成系统能识别的标准xml布局,而原先在布局中添加的”@{}”,”@{三目运算符}”等信息,则会存储在activity_main-layout.xml中。
1 |
|
######activity_main-layout.xml(xml描述文件)
1.任何view只要用到了”@{}”标识,就会在activity_main-layout.xml中生成target描述,并根据该view在parent中的位置生成”binding_[index]”标识,并设置在tag中。 2.如果一个view即没有设置”android:id”,也没有使用”@{}”标识,则不会在activity_main-layout.xml中生成这个view的target描述。 3.LinearLayout比较特殊,并没有设置”android:id”,也没有使用”@{}”,但还是会生成一个默认的tag=”layout/activity_main_0”,表示它是根布局,在ViewDataBinding.java实例化时,需要判断根布局的tag,后面源码会分析到。
1 |
|
####2.生成ActivityMainBinding.java和BR.java
DataBinding根据解析后的activity_main-layout.xml,和layout下的activity_main.xml文件,生成build/intermediates/classes/debug/[项目路径]/databinding/ ActivityMainBinding.java和BR.java
######ActivityMainBinding主要具备以下功能
1.作为view和model的连接器,持有需要展示的数据和views的成员变量 2.将数据映射到view(就是setText,setOnClick等) 3.在UI线程更新数据
######BR.java就是一个常量类
可以通过binding.setVariable(BRuser, new User())进行数据更新
1 |
|
1 |
|
###运行阶段
Databinding框架最主要做的事,就是以上2步,接下来就是在代码中调用生成的ViewDataBinding,并进行数据绑定操作。
######DataBindingUtil是一切的入口
1 |
|
1 |
|
######取出布局的rootView,调用ActivityMainBinding.bind()
1 |
|
此处做了rootView的判断,如果传递过来的不是当前ViewDataBinding绑定的布局,则抛异常。所以即使rootView没有设置id,及”@{}”,在info-layout.xml中也会生成相应的target描述。
1 |
|
这里需要特别注意的是在编译期自动生成的activity_main.xml文件中自动添加了tag=”binding_1”,”binding_2”等,其实在初始化完这些view后,都已经清空,是不影响我们在代码中设置tag的;不过rootView并没有清除tag(就是xml布局最外层的layout),如果>=14以上版本,在代码里设置setTag(R.id.databinding,”anything”),或,<14版本,在代码里设置setTag(“anything”),则会报错,so,这个tag是由DataBinding占着的,使用上得小心。
1 |
|
mapBindings(),其实就是递归遍历view树的过程,不过不是byId,而是byTag,寻找以”binding_“开头的view,并取出”binding_[索引]”中的索引,赋值给binding[]数组。所有的view只在一次遍历中获得,而如果是用findViewById的方式,每次调用都需要遍历一次view树[性能对比]。需要特别注意的是binding数组的元素不一定都是view或viewGroup,如果有include布局的时候binding数组存储的可能是include布局的viewDataBinding对象。
1 |
|
#####view遍历流程图
View都找到了,现在该是时候设置listener,data的时候了。这时候会通过invalidateAll()请求数据更新,层层调用后,还是回到了ActivityMainBinding的executeBindings(),在这个方法里将更新后的model数据,onclick等重新设置到Textview,Button上,完成了model->view的单向绑定。
1 |
|
######以上便是当我们通过DataBindingUtil.setContentView()对Databinding进行初始化,以及当我们获取到最新数据,通过Binding.setModel进行数据更新时的操作流程。
###参考
英文官方文档 https://developer.android.com/topic/libraries/data-binding/index.html
Google开发团队介绍DataDinding使用 https://realm.io/cn/news/data-binding-android-boyar-mount/?utm_source=tuicool&utm_medium=referral
QQ音乐团队分享,比较贴近源码的介绍 http://gold.xitu.io/entry/57e48e7ba22b9d006139c60b