DataBinding源码深入分析

前言

DataBinding 作为MVVM 的一个重要工具,如果对其整体流程了解,在遇到问题时,也能更快的定位解决。下面我们就来分析一下源码。

一、数据绑定

1.1、 UI 跟随 变量值 改变

在使用databinding时,如果是使用非databinding类型的变量,在变量发生变化后,UI界面并不会发生变化

数据变化是视图也跟着变化则需要使用到以下两种方法

  1. 继承BaseObservable
  2. ObservableField,databinding默认实现了一系列实现Observable接口的字段类型
BaseObservable,
ObservableBoolean,
ObservableByte,
ObservableChar,
ObservableDouble,
ObservableField<T>,
ObservableFloat,
ObservableInt,
ObservableLong,
ObservableParcelable<T extends Parcelable>,
ObservableShort,
ViewDataBinding
  1. MutableLiveData
    Android 最近推出的Android Jetpack 其中的livedata也支持数据更新时,视图也能更新。

为了方便,我们把这种 变量值 改变,UI 跟着变化的 变量,叫做databinding变量
这里不再介绍这些,可以去网上搜相关内容或者参考链接

1.2、变量值跟随UI 改变

通过表达式使用@=表达式 就可以在 变量值 跟随UI 改变

这种双向绑定存在一个很大的问题就是死循环。 数据变化(回调监听器)触发UI变化, 然后UI又会触发数据变化(再次回调监听器), 然后一直循环, 设置相同的数据也视为数据变化.

二、基本使用

下面先来介绍一个简单的示例,来引出一些问题。

下面是布局文件,很简单,不用过多说明

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <data>
        <variable
            name="UserBean"
            type="com.xuexuan.data.UserBean">
        </variable>
    </data>


    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:text="@{UserBean.name}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="123123"

            />

        <EditText
            android:id="@+id/tv_age"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="10dp"
            android:text="@={UserBean.name}"
            app:layout_constraintLeft_toRightOf="@+id/tv_name"
            app:layout_constraintTop_toTopOf="parent" />


        <Button
            android:id="@+id/btn"
            app:layout_constraintLeft_toRightOf="@+id/tv_age"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

MainActivity

class MainActivity : AppCompatActivity() {
    //UserBean 里面只有一个ObservableField<String> 变量
    val userBean = UserBean("xuexuan")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mainBinding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        //把数据设置到DataBinding中,有以下两种方式
        //第一种:直接使用DataBinding 为变量生成的设置函数
        mainBinding.setUserBean(userBean)
        //第二种:使用setVariable,参数一传入 BR.UserBean,在代码内部,最后也是调用了setUserBean
        //例如使用模板模式,或者是父类统一处理,则可以使用这种方式,只在子类中设置相应的变量即可
        mainBinding.setVariable(BR.UserBean,userBean)

        btn.setOnClickListener {
            //如果UserBean 的name是String 类型,则在这里改变name值,是无法改变UI的
            //userBean.name = "xuexuan"
            //当前UserBean 的name是ObservableField<String>  类型,则在这里改变name值,是可以改变UI的
            userBean.name?.set("btn_xuexuan")
        }
    }
    
    override fun onResume() {
        super.onResume()
        //如果UserBean 的name是String 类型,则在这里改变name值,也是可以改变UI的
        //userBean.name = "xuexuan"
    }
}
class UserBean(name: String) {
    var name: ObservableField<String>? = ObservableField()
    
    init {
        this.name?.set(name)
    }
}

二、源码分析

在分析源码的时候,大家可能带着这几个问题

  1. 为什么在btn 点击事件 中改变普通变量,UI不能跟着变量值而变化呢?
  2. 为什么在btn 点击事件 中改变databinding变量,UI可以跟着变化呢?
  3. 为什么在onResume 以及之前生命周期 改变普通变量,UI可以跟着变化呢?
  4. 双向绑定,是如何避免死循环的呢?

更新视图的变量类型分为四类, Observable ,ObservableList ,ObservableMap ,LiveData<?> 源码大同小异,这里以Observable 中的ObservableField为例进行分析

ObservableField更新UI源码分析

编译后,会自动在路
app/build/generated/ap_generated_sources/debug/out/com/xuexuan/data/databinding/ActivityMainBindingImpl.java生成对应的代码,其中主干流程就是下面三个函数。

DataBinding 使用观察者模式,当数据发生变化的时候,对UI进行更新,那么我们看一下观察者注册 被观察者 的流程

1、设置变量,让变量的值显示到UI上


    @Override
    public boolean setVariable(int variableId, @Nullable Object variable)  {
        boolean variableSet = true;
        if (BR.UserBean == variableId) {
            //看到这里,你应该明白了,上面的第一种和第二种设置DataBinding变量的联系
            setUserBean((com.zhangl.data.UserBean) variable);
        }
        else {
            variableSet = false;
        }
            return variableSet;
    }

    public void setUserBean(@Nullable com.xuexuan.data.UserBean UserBean) {
        this.mUserBean = UserBean;
        //如果在xml 布局中 中引用了UserBean的成员变量,会生成下面这些代码
        synchronized(this) {
            mDirtyFlags |= 0x2L;
        }
        notifyPropertyChanged(BR.UserBean);
        //这行代码,最后会执行到executeBindings(),后面会详细分析
        super.requestRebind();
    }

2、在executeBindings中进行 订阅,数据发生变化也会调用。

    private  long mDirtyFlags = 0xffffffffffffffffL;
    /* flag mapping
        flag 0 (0x1L): UserBean //脏标志位第1位是1 ,则去更新UserBean的相关UI
        flag 1 (0x2L): null
    flag mapping end*/

    //end


    @Override
    protected void executeBindings() {
        long dirtyFlags = 0;
        synchronized(this) {
           //脏标志位,初始的脏标志位为全1,为了让下面所有的if都可以执行,非第一次执行(数据改变后的执行),会根据这个脏标志位来判断执行那个if
            dirtyFlags = mDirtyFlags;
            mDirtyFlags = 0;
        }
        androidx.databinding.ObservableField<java.lang.String> userBeanName = null;
        com.zhangl.data.UserBean userBean = mUserBean;
        java.lang.String userBeanNameGet = null;

        if ((dirtyFlags & 0x7L) != 0) {



                if (userBean != null) {
                    // read UserBean.name
                    userBeanName = userBean.getName();
                }
                //只有使用databinding 变量,才会有这句代码。
                //这里注册了对userBeanName 的观察,当userBeanName发生变化时,会更新UI(也是在executeBindings 函数中)
                updateRegistration(0, userBeanName);


                if (userBeanName != null) {
                    // read UserBean.name.get()
                    userBeanNameGet = userBeanName.get();
                }
        }
        // batch finished
        if ((dirtyFlags & 0x7L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.editName, userBeanNameGet);
            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.tvName, userBeanNameGet);
        }
        if ((dirtyFlags & 0x4L) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setTextWatcher(this.editName, (androidx.databinding.adapters.TextViewBindingAdapter.BeforeTextChanged)null, (androidx.databinding.adapters.TextViewBindingAdapter.OnTextChanged)null, (androidx.databinding.adapters.TextViewBindingAdapter.AfterTextChanged)null, editNameandroidTextAttrChanged);
        }
    }

注册观察者和更新UI都是通过上面这个函数来完成,
如果你看了代码,会有疑问,难道每次更新数据的是否都会去再订阅一次吗?
是的,因为这个观察者是个弱引用,很可能被系统回收了,所以每次更新数据时都会再去订阅一次。如果订阅关系没有发生变化,则直接返回false(详解下面的代码)

上面问题1、2 的答案,是因为只有使用了databinding 变量 才会 调用updateRegistration 注册观察者,所以当变量发生变化,才会触发UI改变。

3、updateRegistration(0, viewModelIsLoading);可以理解为创建了一个监听。
updateRegistration 有四种类型,主要就是参数类型不一样,四种参数分别对应于Observable ,ObservableList ,ObservableMap ,LiveData<?>,也就是上面所说的databinding变量

源码如下:

    /**
     * @hide
     */
    protected boolean updateRegistration(int localFieldId, Observable observable) {
        return updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
    }

    /**
     * @hide
     */
    protected boolean updateRegistration(int localFieldId, ObservableList observable) {
        return updateRegistration(localFieldId, observable, CREATE_LIST_LISTENER);
    }

    /**
     * @hide
     */
    protected boolean updateRegistration(int localFieldId, ObservableMap observable) {
        return updateRegistration(localFieldId, observable, CREATE_MAP_LISTENER);
    }

    /**
     * @hide
     */
    protected boolean updateLiveDataRegistration(int localFieldId, LiveData<?> observable) {
        mInLiveDataRegisterObserver = true;
        try {
            return updateRegistration(localFieldId, observable, CREATE_LIVE_DATA_LISTENER);
        } finally {
            mInLiveDataRegisterObserver = false;
        }
    }

上面updateRegistration的参数三 CreateWeakListener 是CreateWeakListener接口类型。只有一个create()函数,返回类型是WeakListener

对应上面四种databinding变量,有四种XXXXListener,每一种XXXXListener,都可以返回一个WeakListener 对象,详解下面的代码

    /**
     * Method object extracted out to attach a listener to a bound Observable object.
     */
    private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
        }
    };

    /**
     * Method object extracted out to attach a listener to a bound ObservableList object.
     */
    private static final CreateWeakListener CREATE_LIST_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new WeakListListener(viewDataBinding, localFieldId).getListener();
        }
    };

    /**
     * Method object extracted out to attach a listener to a bound ObservableMap object.
     */
    private static final CreateWeakListener CREATE_MAP_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new WeakMapListener(viewDataBinding, localFieldId).getListener();
        }
    };

    /**
     * Method object extracted out to attach a listener to a bound LiveData object.
     */
    private static final CreateWeakListener CREATE_LIVE_DATA_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new LiveDataListener(viewDataBinding, localFieldId).getListener();
        }
    };

4、WeakListener 是在WeakPropertyListener 里面创建的

    private static class WeakPropertyListener extends Observable.OnPropertyChangedCallback
            implements ObservableReference<Observable> {
        final WeakListener<Observable> mListener;

        public WeakPropertyListener(ViewDataBinding binder, int localFieldId) {
            mListener = new WeakListener<Observable>(binder, localFieldId, this);
        }

        @Override
        public WeakListener<Observable> getListener() {
            return mListener;
        }

        @Override
        public void addListener(Observable target) {
            target.addOnPropertyChangedCallback(this);
        }

        @Override
        public void removeListener(Observable target) {
            target.removeOnPropertyChangedCallback(this);
        }

        @Override
        public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
        }

		//数据更新后,回调到这里去更新UI,下接第12段
        @Override
        public void onPropertyChanged(Observable sender, int propertyId) {
            ViewDataBinding binder = mListener.getBinder();
            if (binder == null) {
                return;
            }
            Observable obj = mListener.getTarget();
            if (obj != sender) {
                return; // notification from the wrong object?
            }
            binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
        }
    }

WeakListener 是一个弱引用类,防止内存泄漏。它 有一个WeakPropertyListener类型的变量mObservable

所以后面的操作,都是通过它的对象来操作。

    private static class WeakListener<T> extends WeakReference<ViewDataBinding> {
        private final ObservableReference<T> mObservable;
        protected final int mLocalFieldId;
        private T mTarget;

        public WeakListener(ViewDataBinding binder, int localFieldId,
                ObservableReference<T> observable) {
            super(binder, sReferenceQueue);
            mLocalFieldId = localFieldId;
            mObservable = observable;
        }

        public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
            mObservable.setLifecycleOwner(lifecycleOwner);
        }

        public void setTarget(T object) {
            unregister();
            mTarget = object;
            if (mTarget != null) {
                mObservable.addListener(mTarget);
            }
        }

        public boolean unregister() {
            boolean unregistered = false;
            if (mTarget != null) {
                mObservable.removeListener(mTarget);
                unregistered = true;
            }
            mTarget = null;
            return unregistered;
        }

        public T getTarget() {
            return mTarget;
        }

        protected ViewDataBinding getBinder() {
            ViewDataBinding binder = get();
            if (binder == null) {
                unregister(); // The binder is dead
            }
            return binder;
        }
    }

5、回到 第三点,开始继续分析 updateRegistration 的源码,最终去执行registerTo

   // observable  参数是ObservableBoolean  类型的,是业务中的值
   // listenerCreator 上面四种CreateWeakListener 之一,通过它的create 可以获取到WeakListener ,WeakListener 的参数mObservable 是WeakPropertyListener类型
    private boolean updateRegistration(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
        if (observable == null) {
            return unregisterFrom(localFieldId);
        }
        //将WeakListener  变量保存在mLocalFieldObservers 因为WeakListener是弱引用,所以需要判空,如果是空的就注册
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            registerTo(localFieldId, observable, listenerCreator);
            return true;
        }
        //listener 和相同的tatget 注册过了,就不需要再注册了
        if (listener.getTarget() == observable) {
            return false;//nothing to do, same object
        }
        unregisterFrom(localFieldId);
        //进行注册
        registerTo(localFieldId, observable, listenerCreator);
        return true;
    }

6、注册监听,如果WeakListener 为空,就是通过listenerCreator.create(this, localFieldId);来创建WeakListener ,最后调用 listener.setTarget(observable);

    protected void registerTo(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
        if (observable == null) {
            return;
        }
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            //调用CreateWeakListener接口 的create,不能的databinding变量,实现了不同的CreateWeakListener接口
            listener = listenerCreator.create(this, localFieldId);
            //这里把新创建的WeakListener 保存在数组,方便下次使用 
            mLocalFieldObservers[localFieldId] = listener;
            if (mLifecycleOwner != null) {
                listener.setLifecycleOwner(mLifecycleOwner);
            }
        }
        //listener 是WeakListener 类型,
        // observable 是业务类型的数据,也就是一种databinding变量,在本例中,就是userBeanName
        listener.setTarget(observable);
    }

7、分析一下,上段代码listener.setTarget(observable); 就是调用WeakListenersetTarget

WeakListener中的setTarget
通过WeakListener 里面的参数来使用WeakPropertyListener,就是保证WeakListener 可以在内存吃紧的时候,可以被回收

	   //这里的T 参数是ObservableField  类型的,是业务中的值
       public void setTarget(T object) {
           unregister();
            mTarget = object;
            if (mTarget != null) {
               // mObservable 就是WeakPropertyListener
               
                mObservable.addListener(mTarget);
            }
       }

调用了WeakPropertyListeneraddListener

        @Override
        public void addListener(Observable target) {
           //参数是`OnPropertyChangedCallback` 类型,这里传入的参数是this,因为WeakPropertyListener变量,实现了接口`OnPropertyChangedCallback` 
           //target 是Observable 类型 (ObservableField)
            target.addOnPropertyChangedCallback(this);
        }

8、target.addOnPropertyChangedCallback(this);调用了BaseObservableaddOnPropertyChangedCallback函数

所有的databinding 变量都继承BaseObservable

public class BaseObservable implements Observable {
    private transient PropertyChangeRegistry mCallbacks;

    public BaseObservable() {
    }

	//这里的参数callback,就是WeakPropertyListener变量,因为它实现了接口OnPropertyChangedCallback 
    @Override
    public void addOnPropertyChangedCallback(@NonNull OnPropertyChangedCallback callback) {
        synchronized (this) {
            if (mCallbacks == null) {
                mCallbacks = new PropertyChangeRegistry();
            }
        }
        //终于到了观察者订阅的地方,(本例子来看,BaseObservable 就是ObservableField)
        // 相当于把一个观察者 callback,与被观察者BaseObservable  ,建立联系,当BaseObservable 的数据发生变化,通知到callback,实现相应的UI更新
        mCallbacks.add(callback);
    }

     ...省略部分函数...

    /**
     * Notifies listeners that all properties of this instance have changed.
     * databinding 变量的数据发生变化后,最先会调用到这里
     */
    public void notifyChange() {
        synchronized (this) {
            if (mCallbacks == null) {
                return;
            }
        }
        //这一句代码,最终会调用到下面的第9点的callback.onPropertyChanged(sender, arg);
        mCallbacks.notifyCallbacks(this, 0, null);
    }

    ...省略部分函数...
}

9、上面的创建了PropertyChangeRegistry,来看一下它都做了些什么

  • 实现了接口 CallbackRegistry.NotifierCallback ,赋值给变量NOTIFIER_CALLBACK
  • 这个类是继承CallbackRegistry,调用 super(NOTIFIER_CALLBACK);把这个接口的实现,传递给CallbackRegistry的变量mNotifier,mNotifier主要是在databinding变量数据更新后,回调的时候使用,下面会介绍到。
public class PropertyChangeRegistry extends
        CallbackRegistry<Observable.OnPropertyChangedCallback, Observable, Void> {

    private static final CallbackRegistry.NotifierCallback<Observable.OnPropertyChangedCallback, Observable, Void> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback<Observable.OnPropertyChangedCallback, Observable, Void>() {
        @Override
        public void onNotifyCallback(Observable.OnPropertyChangedCallback callback, Observable sender,
                int arg, Void notUsed) {
            //数据更新后,调用WeakPropertyListener的onPropertyChanged()
            callback.onPropertyChanged(sender, arg);
        }
    };

    public PropertyChangeRegistry() {
        super(NOTIFIER_CALLBACK);
    }

    /**
     * Notifies registered callbacks that a specific property has changed.
     *
     * @param observable The Observable that has changed.
     * @param propertyId The BR id of the property that has changed or BR._all if the entire
     *                   Observable has changed.
     */
    public void notifyChange(@NonNull Observable observable, int propertyId) {
        notifyCallbacks(observable, propertyId, null);
    }
}

10、观察者就已经订阅好了,接下来看一下,如果数据发生变化,是怎么去更新UI的。

数据发生变化,例如调用:ObservableField系列的set()

    public void set(boolean value) {
        //这里的判断,避免了双向绑定的死循环
        if (value != mValue) {
            mValue = value;
            //数据更新后,这个函数就是第8段代码的notifyChange()
            notifyChange();
        }
    }

11、第8段代码的notifyChange()调用的mCallbacks.notifyCallbacks(this, 0, null);最终会到下面这段代码,这里的mNotifier就是第9段代码的PropertyChangeRegistry 的父类变量

    private void notifyCallbacks(T sender, int arg, A arg2, final int startIndex,
            final int endIndex, final long bits) {
        long bitMask = 1;
        for (int i = startIndex; i < endIndex; i++) {
            if ((bits & bitMask) == 0) {
            //数据更新后,调用PropertyChangeRegistry中的接口变量的函数
                mNotifier.onNotifyCallback(mCallbacks.get(i), sender, arg, arg2);
            }
            bitMask <<= 1;
        }
    }

12、分析一下mNotifier.onNotifyCallback,其中mNotifier 就是PropertyChangeRegistry 中的NOTIFIER_CALLBACK(看第9段代码),调用callback.onPropertyChanged(sender, arg);—>调用第4段中的WeakPropertyListener的onPropertyChanged()

13、第4段代码中的, binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);调用了下面的这个函数,onFieldChange()是一个抽象函数,它的实现类,就是编译时候生成的xxxxxBindingImpl.java,因此就是调用第2段代码中的onFieldChange(),判断是否需要改变,最终在 requestRebind();中调用了第3段代码 executeBindings()实现了对UI的更新

    private void handleFieldChange(int mLocalFieldId, Object object, int fieldId) {
        if (mInLiveDataRegisterObserver) {
            // We're in LiveData registration, which always results in a field change
            // that we can ignore. The value will be read immediately after anyway, so
            // there is no need to be dirty.
            return;
        }
        boolean result = onFieldChange(mLocalFieldId, object, fieldId);
        if (result) {
            requestRebind();
        }
    }

14、onFieldChange 回调到 XXXXBindingImpl.java 类中调用


    @Override
    protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
        switch (localFieldId) {
            case 0 :
                return onChangeUserBeanName((androidx.databinding.ObservableField<java.lang.String>) object, fieldId);
        }
        return false;
    }
    private boolean onChangeUserBeanName(androidx.databinding.ObservableField<java.lang.String> UserBeanName, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    //脏标志位,数据更新后,用于在第三段代码中判断哪些if语句需要执行
                    mDirtyFlags |= 0x1L;
            }
            return true;
        }
        return false;
    }

15、来看一下requestRebind(),可以看到最终是通过异步发送消息

    protected void requestRebind() {
        if (mContainingBinding != null) {
            mContainingBinding.requestRebind();
        } else {
            final LifecycleOwner owner = this.mLifecycleOwner;
            if (owner != null) {
                Lifecycle.State state = owner.getLifecycle().getCurrentState();
                if (!state.isAtLeast(Lifecycle.State.STARTED)) {
                    return; // wait until lifecycle owner is started
                }
            }
            synchronized (this) {
                if (mPendingRebind) {
                    return;
                }
                mPendingRebind = true;
            }
            //boolean USE_CHOREOGRAPHER = SDK_INT >= 16;
            if (USE_CHOREOGRAPHER) {
                mChoreographer.postFrameCallback(mFrameCallback);
            } else {
                mUIThreadHandler.post(mRebindRunnable);
            }
        }
    }

注意这里更新UI是异步的,所以在java代码中,更新databinding的数据,之后马上又去设置ui值,可能最后会被databinding的值覆盖。
异步执行的Runnable ,代码如下

    private final Runnable mRebindRunnable = new Runnable() {
        @Override
        public void run() {
            synchronized (this) {
                mPendingRebind = false;
            }
            processReferenceQueue();

            if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
                // Nested so that we don't get a lint warning in IntelliJ
                if (!mRoot.isAttachedToWindow()) {
                    // Don't execute the pending bindings until the View
                    // is attached again.
                   mRoot.removeOnAttachStateChangeListener(ROOT_REATTACHED_LISTENER);
                    mRoot.addOnAttachStateChangeListener(ROOT_REATTACHED_LISTENER);
                    return;
                }
            }
            executePendingBindings();
        }
    };

下面的代码很简单,看注释的那几句关键代码

    public void executePendingBindings() {
        if (mContainingBinding == null) {
           //执行了这句代码
            executeBindingsInternal();
        } else {
            mContainingBinding.executePendingBindings();
        }
    }
    private void executeBindingsInternal() {
        if (mIsExecutingPendingBindings) {
            requestRebind();
            return;
        }
        if (!hasPendingBindings()) {
            return;
        }
        mIsExecutingPendingBindings = true;
        mRebindHalted = false;
        if (mRebindCallbacks != null) {
            mRebindCallbacks.notifyCallbacks(this, REBIND, null);

            // The onRebindListeners will change mPendingHalted
            if (mRebindHalted) {
                mRebindCallbacks.notifyCallbacks(this, HALTED, null);
            }
        }
        if (!mRebindHalted) {
            //这里最终会调用到第三段代码,对UI进行更新
            executeBindings();
            if (mRebindCallbacks != null) {
                mRebindCallbacks.notifyCallbacks(this, REBOUND, null);
            }
        }
        mIsExecutingPendingBindings = false;
    }

三、生命周期相关

在ViewDataBindding 类中

每个xml 对应的Binding 类,都是继承ViewDataBindding,这里以示例代码的为例,获取ActivityMainBinding,就会执行ViewDataBindding的构造函数,静态函数等

  val mainBinding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

3.1 ViewDataBinding构造函数

在ViewDataBinding类中
    private static final boolean USE_CHOREOGRAPHER = SDK_INT >= 16;
    protected ViewDataBinding(DataBindingComponent bindingComponent, View root, int localFieldCount) {
        mBindingComponent = bindingComponent;
        mLocalFieldObservers = new WeakListener[localFieldCount];
        //这个root,是xml中的最顶层view,也就是contentView
        this.mRoot = root;

        //对本例而言,这里是true
        if (USE_CHOREOGRAPHER) {
            mChoreographer = Choreographer.getInstance();
            mFrameCallback = new Choreographer.FrameCallback() {
                @Override
                public void doFrame(long frameTimeNanos) {
                    mRebindRunnable.run();
                }
            };
        } else {
            mFrameCallback = null;
            mUIThreadHandler = new Handler(Looper.myLooper());
        }
    }

3.2 mRebindRunnable

    /**
     * Runnable executed on animation heartbeat to rebind the dirty Views.
     */
    private final Runnable mRebindRunnable = new Runnable() {
        @Override
        public void run() { 
            。。。省略代码。。。

            if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
                // Nested so that we don't get a lint warning in IntelliJ
                //如果mRoot 这个view 还没有attached 到Window,就为mRoot 设置一个Attach的回调
                if (!mRoot.isAttachedToWindow()) {
                    // Don't execute the pending bindings until the View
                    // is attached again.
                    mRoot.removeOnAttachStateChangeListener(ROOT_REATTACHED_LISTENER);
                    //设置 mRoot(xml 的根view) 在Attach的时候的回调 接口
                    mRoot.addOnAttachStateChangeListener(ROOT_REATTACHED_LISTENER);
                    return;
                }
            }
            //这里最终是更新UI
            executePendingBindings();
        }
    };

3.3 ROOT_REATTACHED_LISTENER 回调接口

    static {
        if (VERSION.SDK_INT < VERSION_CODES.KITKAT) {
            ROOT_REATTACHED_LISTENER = null;
        } else {
            ROOT_REATTACHED_LISTENER = new OnAttachStateChangeListener() {
                @TargetApi(VERSION_CODES.KITKAT)
                @Override
                public void onViewAttachedToWindow(View v) {
                    // execute the pending bindings.
                    final ViewDataBinding binding = getBinding(v);
                    //回调到 mRebindRunnable,这次是view 已经attached 到window了,所以到mRebindRunnable中会执行executePendingBindings();
                    binding.mRebindRunnable.run();
                    v.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                }
            };
        }
    }

3.4 requestRebind

获取每个xml 对应的Binding 类时(本例特指ActivityMainBindingImpl ),会调用 requestRebind()

    protected void requestRebind() {
        if (mContainingBinding != null) {
            mContainingBinding.requestRebind();
        } else {
             。。。省略代码。。。
            if (USE_CHOREOGRAPHER) {
                //通过post 执行mFrameCallback
                mChoreographer.postFrameCallback(mFrameCallback);
            } else {
                mUIThreadHandler.post(mRebindRunnable);
            }
        }
    }

关键的几个函数都了解后,我们来看看具体流程,

ActivityMainBindingImpl()->requestRebind()->mFrameCallback.doFrame() ->mRebindRunnable.run() ->mRoot.addOnAttachStateChangeListener(ROOT_REATTACHED_LISTENER);

到此为止,已经注册了View Attach 的回调函数。

在生命周期执行onResume addView -> performTraversals,-> View listener.onViewAttachedToWindow(this);
因为上面已经为mRoot(xml 根view)注册了这个事件的回调,所以回调到ROOT_REATTACHED_LISTENER .onViewAttachedToWindow()中-> mRebindRunnable.run() ->mRebindRunnable .run()->executePendingBindings();

那么上面问题3 就应该明了了,因为在onResume 之后,会自动执行一次executePendingBindings(); 来更新界面

至此,databinding的流程就算分析完了,其中省略了一些代码,大家可自行追踪代码

©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页