Android中的DataBinding的原理浅析

一、什么是DataBinding

知道DataBinding的应该也会知道MVVM设计模式,该模式实现了View与Model的双向绑定从而实现了View和Model的同步更新。MVVM是一种架构思想而DataBinding就是实现这一思想的工具。

二、DataBinding的使用

我们要对DataBinding进行原理分析前,首先要会使用DataBinding。
在build.gradel中配置DataBinding

android {
    ...
    dataBinding{
        enabled true
    }
}

对View的布局文件进行配置,使用layout作为跟布局标签。使用data标签进行DataBinding的绑定。控件中可以使用@{}进行绑定,@{}为单向绑定@={}为双向绑定



    
    
        
        
    
    
        
        
        
    

声明一个数据类,使用ObservableField声明属性并通过范型指定数据类型。

public class UserInfo {
    public ObservableField userName = new ObservableField<>();
    public ObservableField passWord = new ObservableField<>();
}

在Activity中进行绑定

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        var binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        var userInfo = UserInfo()
        userInfo.userName.set("xixi")
        userInfo.passWord.set("123")
        binding.userInfo = userInfo
    }
}

以上就是一个通过DataBinding实现双向绑定的例子。

三、Data Binding的原理分析

我们通过上面的例子对DataBinding进行原理分析。首先我们要知道DataBinding使用了apt技术,我们build项目时DataBinding会生成多个文件,我们可以在build文件中查看

图片.png
图片.png

DataBinding还将原有的activity_main.xml文件进行了拆分,分别是activity_mian.xml和activity_main-layout.xml。

activity_main.xml

通过上面的代码我们发现DataBinding将原有的layout和data标签去除了。并为根布局声明了一个layout/文件名_0的tag,为其他使用到@{}或@={}的控件按顺序添加了一个binding_X的tag。

activity_main-layout.xml

该配置文件中详细的记述了 我们声明的全局变量,变量指向的数据类型的绝对路径。tag对应的View类型。控件绑定具体属性和Model中的具体属性。true是否是双向的。

接下来我们通过Activity中的 var binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)进行入手

方法中通过activity的setContentView加载布局,并通过window找到id为content的ViewGroup,它是一个FrameLayout用于加载我们添加的布局文件。接下来就是bindToAddedViews方法。

parent中的子View就是我们布局文件中的根布局LinearLayout,所以走的是if中的代码

bind方法又调用了DataBinderMapperImpl中的getDataBinder方法。

通过一系列的条件判断之后返回了一个ActivityMainBindingImpl对象,接下来我们看它的构造方法。

上面的代码看着非常的多,但是它就是将布局中的含有databinding赋值的tag控件一一存入bindings的Object的数组中并返回。

该方法中将获取的View数组赋值给成员变量,接下来看invalidateAll()方法。

上面代码调用过来就是为了执行mRebindRunnable。在看该Runnable中的executePendingBindings()方法

上面也是对一些状态进行了判断添加一下回调,主要的还是executeBindings()方法。

看了上面的方法是不是有一种终于熬到头的感觉了呢,当((dirtyFlags & 0xeL) != 0)或((dirtyFlags & 0xdL) != 0)成立时就会把Model中的数据set到相应的View中,这个就是单向的M->V。((dirtyFlags & 0x8L) != 0)成立时就是V->M它为双向绑定的控件添加了一个内容变化的监听mboundView1androidTextAttrChanged

当控件中的内容发生变化时,就会更新到Model上。

activity中为userInfo赋的值就是上面的mUserInfo。
通过上面的代码我们对DataBinding的绑定过程又了一定的了解,但是还有两个问题我们没有解决,那就是View和Model的变化有时在哪里监听的呢。

还记得上面的mRebindRunnable吗?通过对它的查找我们在ViewDataBinding的静态代码块中发现了端倪。

看到上面的代码是不是一下就明白了V的变化监听了呢。

DataBinding通过布局中的tag将控件查找出来,然后根据生成的配置文件将V与M进行对应的同步操作,设置一个全局的布局变化监听来实时更新,M通过他的set方法进行同步。

该文档是自己的学习记录如有错误欢迎指出。

你可能感兴趣的:(Android中的DataBinding的原理浅析)