android开发之DataBinding的使用以及源码深度分析

android开发之DataBinding的使用以及源码深度分析,第1张

一、DataBinding简介

Data binding 在2015年7⽉发布的Android Studio v1.3.0 版本上引⼊,在2016年4月Android Studio v2.0.0 上正式⽀持。⽬前为⽌,DataBinding 已经⽀持双向绑定了。Databinding 是⼀个实现数据和UI绑定的框架,是⼀个实现 MVVM 模式的⼯具,有了 Data Binding,在Android中也可以很⽅便的实现MVVM开发模式。Data Binding 是⼀个support库,最低⽀持到Android 2.1(API Level 7+)。Data Binding 的作用就是可以通过声明式布局来绑定xml,使用了DataBinding,我们就不用在java类中写findViewById、setText,setVisibility,setEnabled、setOnClickListener等这些大量重复的代码,因为DataBinding的原理实际上就是通过APT技术,在编译的时候自动帮我们把这些代码写了,我们只需要对它进行绑定就可以了,使用DataBinding能够轻松实现MVVM模式。

二、DataBinding的使用(Kotlin版)

注意:在使用DataBinding的时候,一定要在build.gradle中把DataBinding的开关打开:

dataBinding{
    enabled true
}

1、activity_main.xml



    
       
    
    
        
        
    

2、User.kt

class User {
    val name:ObservableField by lazy { ObservableField() }
    val pwd:ObservableField by lazy { ObservableField() }
}

3、MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //绑定布局
        val bing = DataBindingUtil.setContentView 
                             (this,R.layout.activity_main4)
        //设置数据来源
        val user = User()
        user.name.set("张三")
        user.pwd.set("123456")
        bing.user = user
    }
}
三、DataBinding的源码分析 1、xml布局分析

首先,我们分析布局变化,前面已经说过,DataBinding是通过APT技术来实现的,也就是说,在我们绑定了布局并且编译之后,编译工具会自动生成一些布局相关的代码,因此,我们可以打开编译后生成的布局文件来进行分析,具体路径:build\intermediates\data_binding_layout_info_type_merge\debug\out\activity_main.xml




    
        
    

    
        
            
            
        
        
            
                
                    
                    false
                    
                
            
            
        
        
            
                
                    
                    false
                    
                
            
            
        
    

可以看到,编译工具生成的布局文件定义了了多个Target标签,这些Target的定义,其实就是定义对应的tag,将tag与activity_main.xml布局中的对应的View的id对应起来经过DataBinding变化后的布局,就会有多个tag,同时打开build\intermediates\incremental\mergeDebugResources\stripped.dir\layout\activity_main.xml,我们竟然可以看到没有任何绑定的的xml布局:


    
        

        
    
         

也就是说,DataBinding帮我们把我们在开发过程中编写的xml布局分成了两个部分,一部分是通过定义Target来把View和id关联起来,另一部分就是去掉了DataBinding的布局本身。

2、DataBindingUtil.setContentView原理
 DataBindingUtil.setContentView(this,R.layout.activity_main4)

(1)DataBindingUtil.setContentView()

点进去看源码,我们会发现,其实DataBindingUtil的setContentView方法,主要就是调用了activity的setContentView设置布局,并且绑定添加对应的View:

 public static  T setContentView(@NonNull Activity activity,
            int layoutId, @Nullable DataBindingComponent bindingComponent) {
        activity.setContentView(layoutId);
        View decorView = activity.getWindow().getDecorView();
        ViewGroup contentView = (ViewGroup) decorView.findViewById(android.R.id.content);
        return bindToAddedViews(bindingComponent, contentView, 0, layoutId);
    }
private static  T bindToAddedViews(DataBindingComponent component,
            ViewGroup parent, int startChildren, int layoutId) {
        final int endChildren = parent.getChildCount();
        final int childrenAdded = endChildren - startChildren;
        if (childrenAdded == 1) {
            final View childView = parent.getChildAt(endChildren - 1);
            return bind(component, childView, layoutId);
        } else {
            final View[] children = new View[childrenAdded];
            for (int i = 0; i < childrenAdded; i++) {
                children[i] = parent.getChildAt(i + startChildren);
            }
            return bind(component, children, layoutId);
        }
    }

(2)DataBindingUtil.bind()方法

 static  T bind(DataBindingComponent bindingComponent, View[] roots,
            int layoutId) {
        return (T) sMapper.getDataBinder(bindingComponent, roots, layoutId);
    }

这里的sMapper是一个DataBinderMapper对象,其实现类是DataBinderMapperImpl,DataBinderMapperImpl是通过apt注解处理器生成的(生成的文件目录位置:build\generated\ap_generated_sources\debug\out\包名),这里的sMapper.getDataBinder()其实就是调用了MergedDataBinderMapper的getDataBinder()方法,而sMapper中的数据,其实就是DataBinderMapperImpl的构造器中调用其父类MergedDataBinderMapper的addMapper()方法添加的对象。

public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
    int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
    if(localizedLayoutId > 0) {
      final Object tag = view.getTag();
      if(tag == null) {
        throw new RuntimeException("view must have a tag");
      }
      switch(localizedLayoutId) {
        case  LAYOUT_ACTIVITYMAIN4: {
          if ("layout/activity_main4_0".equals(tag)) {
            return new ActivityMain4BindingImpl(component, view);
          }
          throw new IllegalArgumentException("The tag for activity_main4 is invalid. Received: " + tag);
        }
      }
    }
    return null;
  }

在getDataBinder方法里,需要注意两点,就是如果布局的顶层View,比如tag为layout/activity_main_0,那么就会new出一个ActivityMainBindingImpl对象。这个tag其实可以从前面看到的build\intermediates\incremental\mergeDebugResources\stripped.dir\layout\activity_main.xml布局中的LinearLayout的tag得知。

(3)ActivityMainBindingImpl构造器

通过apt注解器生成的ActivityMainBindingImpl这个对象,会对View进行一些绑定 *** 作,把通过tag取出的View与ActivityMainBindingImpl中对应的View属性进行绑定。

 public ActivityMain4BindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
        this(bindingComponent, root, mapBindings(bindingComponent, root, 3, sIncludes, sViewsWithIds));
    }
 protected static Object[] mapBindings(DataBindingComponent bindingComponent, View root,
            int numBindings, IncludedLayouts includes, SparseIntArray viewsWithIds) {
        Object[] bindings = new Object[numBindings];
        mapBindings(bindingComponent, root, bindings, includes, viewsWithIds, true);
        return bindings;
    }

在这里会调用一个mapBindings方法,第三个参数的意思是布局文件下的节点数(例如我的activity_main.xml里有3个节点,而生成的是3)。这里值得注意的是,mapBindings返回的是一个Object[] bindings数组,其实就是将布局中的View保存在对应的bindings数组中,然后取出这个数组中的数据赋值给ActivityMainBindingImpl中的View,这个 *** 作是很消耗性能的。

而ActivityMainBindingImpl的父类,其实就位置于build\generated\data_binding_base_class_source_out\debug\out\包名下:

public abstract class ActivityMain4Binding extends ViewDataBinding {
  @Bindable
  protected User mUser;

  protected ActivityMain4Binding(Object _bindingComponent, View _root, int _localFieldCount) {
    super(_bindingComponent, _root, _localFieldCount);
  }

  public abstract void setUser(@Nullable User user);

  @Nullable
  public User getUser() {
    return mUser;
  }
...
}
4、ActivityMainBinding.setUser解析 

(1)BR文件

public class BR {
  public static final int _all = 0;

  public static final int user = 1;
}

BR文件位于build\generated\ap_generated_sources\debug\out\包名下,其作用是定义不同的属性值来标记不同的 *** 作需要的监听在mLocalFieldObservers数组中的位置。

(2)ActivityMain4BindingImpl.setUser()

 public void setUser(@Nullable com.yexing.databinding.User User) {
        this.mUser = User;
        synchronized(this) {
            mDirtyFlags |= 0x4L;
        }
         //通知user保存数据
        notifyPropertyChanged(BR.user);
        super.requestRebind();
    }

(3)ViewDataBind.updateRegistration()

 private boolean updateRegistration(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
        if (observable == null) {
            return unregisterFrom(localFieldId);
        }
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            registerTo(localFieldId, observable, listenerCreator);
            return true;
        }
         //根据BR的每个属性的属性值做index,存储每个BR属性对应的监听器
        if (listener.getTarget() == observable) {
            return false;//nothing to do, same object
        }
        unregisterFrom(localFieldId);
        registerTo(localFieldId, observable, listenerCreator);
        return true;
    }


 //这个方法其实就是将Activity这个观察者和User这个被观察者统一添加到ObservableFeference中
 protected void registerTo(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
        if (observable == null) {
            return;
        }
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            //通过属性监听器的创建器创建一个BR属性值对应的监听器
            listener = listenerCreator.create(this, localFieldId);
            mLocalFieldObservers[localFieldId] = listener;
            //将监听器与观察者做绑定,这里的观察者其实就是activity
            if (mLifecycleOwner != null) {
                listener.setLifecycleOwner(mLifecycleOwner);
            }
        }
        //将监听器与被观察者做绑定,被观察者是User
        listener.setTarget(observable);
    }

这里通过WeakListener监听器中的ObservableReference对象保存观察者与被观察者,当被观察者发生改变的时候,就会找到对应的WeakListener监听器,然后通知观察者做修改。这里的listner.setTarget()其实就是通过WeakPropertyListener给被观察者添加callback,然后当被观察者数据发生改变的时候,被观察者通过遍历其内部的PropertyChangeRegistry中的OnPropertyChangedCallback回调,然后通过WeakPropertyListener监听通知给ViewDataBinding以及其实现类ActivityMainBindImpl具体进行数据的处理和设置。

(4)WeakListener.setTarget()

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

这里的mTarget是一个泛型对象,这个泛型是在WeakPropertyListener初始化WeakListener的时候传入的一个Observable,这个是databinding中的Observable,其子类实现就是BaseObservable。WeakPropertyListener中的addListener方法会给Observable添加一个callback回调,向Observable这个被观察者中添加callback的目的,就是在Observable数据发生变化的时候,遍历Observable中的mCallbacks这个集合,通知观察者进行修改,这个 *** 作也是相当消耗性能的。

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

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

        @Override
        public WeakListener 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) {
        }

        @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);
        }
    }

BaseObservable这个被观察者会被WeakListener持有,而WeakListener会被WeakPropertyListener持有,从而BaseObservable会间接的被WeakPropertyListener持有。而BaseObservable会通过mCallbacks持有Observable.OnPropertyChangedCallback对象,而Observable.OnPropertyChangedCallback的子类是WeakPropertyListener,所以BaseObservable也会持有WeakPropertyListener对象。而WeakPropertyListener和WeakListener是相互持有的,在完成监听并且给Observable添加了回调之后,就会回到ActivityMainBindImpl的setUser()方法继续执行notifyPropertyChanged()方法。

(5)Observable.notifyPropertyChanged()方法

 /**
     * Notifies listeners that a specific property has changed. The getter for the property
     * that changes should be marked with {@link Bindable} to generate a field in
     * BR to be used as fieldId.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    public void notifyPropertyChanged(int fieldId) {
        synchronized (this) {
            if (mCallbacks == null) {
                return;
            }
        }
        mCallbacks.notifyCallbacks(this, fieldId, null);
    }
/**
     * Notify all callbacks.
     *
     * @param sender The originator. This is an opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     * @param arg An opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     * @param arg2 An opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     */
    public synchronized void notifyCallbacks(T sender, int arg, A arg2) {
        mNotificationLevel++;
        notifyRecurse(sender, arg, arg2);
        mNotificationLevel--;
        if (mNotificationLevel == 0) {
            if (mRemainderRemoved != null) {
                for (int i = mRemainderRemoved.length - 1; i >= 0; i--) {
                    final long removedBits = mRemainderRemoved[i];
                    if (removedBits != 0) {
                        removeRemovedCallbacks((i + 1) * Long.SIZE, removedBits);
                        mRemainderRemoved[i] = 0;
                    }
                }
            }
            if (mFirst64Removed != 0) {
                removeRemovedCallbacks(0, mFirst64Removed);
                mFirst64Removed = 0;
            }
        }
    }

    /**
     * Notify up to the first Long.SIZE callbacks that don't have a bit set in removed.
     *
     * @param sender The originator. This is an opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     * @param arg An opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     * @param arg2 An opaque parameter passed to
     * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)}
     */
    private void notifyFirst64(T sender, int arg, A arg2) {
        final int maxNotified = Math.min(Long.SIZE, mCallbacks.size());
        notifyCallbacks(sender, arg, arg2, 0, maxNotified, mFirst64Removed);
    }

    /**
     * Notify all callbacks using a recursive algorithm to avoid allocating on the heap.
     * This part captures the callbacks beyond Long.SIZE that have no bits allocated for
     * removal before it recurses into {@link #notifyRemainder(Object, int, A, int)}.
     *
     * 

Recursion is used to avoid allocating temporary state on the heap.

* * @param sender The originator. This is an opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg2 An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} */ private void notifyRecurse(T sender, int arg, A arg2) { final int callbackCount = mCallbacks.size(); final int remainderIndex = mRemainderRemoved == null ? -1 : mRemainderRemoved.length - 1; // Now we've got all callbakcs that have no mRemainderRemoved value, so notify the // others. notifyRemainder(sender, arg, arg2, remainderIndex); // notifyRemainder notifies all at maxIndex, so we'd normally start at maxIndex + 1 // However, we must also keep track of those in mFirst64Removed, so we add 2 instead: final int startCallbackIndex = (remainderIndex + 2) * Long.SIZE; // The remaining have no bit set notifyCallbacks(sender, arg, arg2, startCallbackIndex, callbackCount, 0); } /** * Notify callbacks that have mRemainderRemoved bits set for remainderIndex. If * remainderIndex is -1, the first 64 will be notified instead. * * @param sender The originator. This is an opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg2 An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param remainderIndex The index into mRemainderRemoved that should be notified. */ private void notifyRemainder(T sender, int arg, A arg2, int remainderIndex) { if (remainderIndex < 0) { notifyFirst64(sender, arg, arg2); } else { final long bits = mRemainderRemoved[remainderIndex]; final int startIndex = (remainderIndex + 1) * Long.SIZE; final int endIndex = Math.min(mCallbacks.size(), startIndex + Long.SIZE); notifyRemainder(sender, arg, arg2, remainderIndex - 1); notifyCallbacks(sender, arg, arg2, startIndex, endIndex, bits); } } /** * Notify callbacks from startIndex to endIndex, using bits as the bit status * for whether they have been removed or not. bits should be from mRemainderRemoved or * mFirst64Removed. bits set to 0 indicates that all callbacks from startIndex to * endIndex should be notified. * * @param sender The originator. This is an opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param arg2 An opaque parameter passed to * {@link CallbackRegistry.NotifierCallback#onNotifyCallback(Object, Object, int, Object)} * @param startIndex The index into the mCallbacks to start notifying. * @param endIndex One past the last index into mCallbacks to notify. * @param bits A bit field indicating which callbacks have been removed and shouldn't * be notified. */ 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) { mNotifier.onNotifyCallback(mCallbacks.get(i), sender, arg, arg2); } bitMask <<= 1; } }

这里的mNotifyer.notifyCallback其实就会调用到下面的PropertyChangeRegistry中定义的NOTIFYER_CALLBACK属性中的onNotifyCallback实现,而这里的callback其实就是WeakPropertyListener,因为WeakPropertyListener是OnPropertyChangedCallback的子类,这里会回调给mLocalFieldObservers数组中所有的WeakListener。

public class PropertyChangeRegistry extends
        CallbackRegistry {

    private static final CallbackRegistry.NotifierCallback NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback() {
        @Override
        public void onNotifyCallback(Observable.OnPropertyChangedCallback callback, Observable sender,
                int arg, Void notUsed) {
            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);
    }
}

而这里的callback.onPropertyChanged(sender, arg);则会回调到ViewDataBinding类中的WeakPropertyListener.onPropertyChanged:

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

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

        @Override
        public WeakListener 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) {
        }

        @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);
        }
    }

从mListener中取出target,而这里的mListener其实就是WeakListener,而每个被观察者,其实都 是有一个对应的LocalFieldId,这个id就是BR文件中定义中的id。

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();
        }
    }

这里的handleFieldChange方法,在我们生成的ActivityMainBindingImpl也有实现:

@Override
    protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
        switch (localFieldId) {
            case 0 :
                return onChangeUserName((androidx.databinding.ObservableField) object, fieldId);
            case 1 :
                return onChangeUserPwd((androidx.databinding.ObservableField) object, fieldId);
        }
        return false;
    }
    private boolean onChangeUserName(androidx.databinding.ObservableField UserName, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x1L;
            }
            return true;
        }
        return false;
    }
    private boolean onChangeUserPwd(androidx.databinding.ObservableField UserPwd, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x2L;
            }
            return true;
        }
        return false;
    }

因为我们之前传入的localFieldId = 0,所以会返回true,即会返回到ViewDataBinding.java中的handleFieldChange方法,继续执行requestRebind():

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();
        }
    }



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;
            }
            if (USE_CHOREOGRAPHER) {
                mChoreographer.postFrameCallback(mFrameCallback);
            } else {
                mUIThreadHandler.post(mRebindRunnable);
            }
        }
    }

这里最终会通过mUIThreadHandler.post(mRebindRunnable);执行mRebindRunnable里面的run方法:

 /**
     * Runnable executed on animation heartbeat to rebind the dirty Views.
     */
    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();
        }
    };

然后执行到executePendingBindings()方法,而方法的实现又是在我们生成的MainActivityBindingImpl里:

 @Override
    protected void executeBindings() {
        long dirtyFlags = 0;
        synchronized(this) {
            dirtyFlags = mDirtyFlags;
            mDirtyFlags = 0;
        }
        androidx.databinding.ObservableField userName = null;
        java.lang.String userPwdGet = null;
        com.yexing.databinding.User user = mUser;
        java.lang.String userNameGet = null;
        androidx.databinding.ObservableField userPwd = null;

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


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

                    if (user != null) {
                        // read user.name
                        userName = user.getName();
                    }
                    updateRegistration(0, userName);


                    if (userName != null) {
                        // read user.name.get()
                        userNameGet = userName.get();
                    }
            }
            if ((dirtyFlags & 0xeL) != 0) {

                    if (user != null) {
                        // read user.pwd
                        userPwd = user.getPwd();
                    }
                    updateRegistration(1, userPwd);


                    if (userPwd != null) {
                        // read user.pwd.get()
                        userPwdGet = userPwd.get();
                    }
            }
        }
        // batch finished
        if ((dirtyFlags & 0xdL) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.mboundView1, userNameGet);
        }
        if ((dirtyFlags & 0xeL) != 0) {
            // api target 1

            androidx.databinding.adapters.TextViewBindingAdapter.setText(this.mboundView2, userPwdGet);
        }
    }

这个方法其实就是执行了setText *** 作,也就是调用了页面布局的View的setText把数据显示出来。到此,DataBinding的源码分析完成。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/904787.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存