android databinding 生成xxxBing类内部执行和刷新的流程

再编译期,使用注解处理器生成对应的xxxdatabinding 类继承ViewDataBinding

并记录了从layoutId   对应到  自动生成的Bind类
对于带有id的类,会生成成员变量

查找子View的方式是,遍历rootView,的子View,然后把需要查找的View,放到对应的数组中
从数据中取出值,赋值给对应的View成员变量


核心方法

//子类必须重写的方法,内部会根据属性的flag值,是否已经修改,来决定是否更新对应的属性, protected void executeBindings()

我们先从,绑定数据开始

   public void setModel(Model model)  setXX 代表我们布局中设置的数据,设置数据的方法
    public void setModel(@Nullable com.daodian8.store.mine.ui.activity.RechargeAndDeductActivity Model) {
        this.mModel = Model;
        synchronized(this) {
            mDirtyFlags |= 0x2L;
        }
        notifyPropertyChanged(BR.model);//会通知更新对应的属性id
        super.requestRebind();//会申请重新绑定,内部,会请求,一个同步信号,再同步信号的回调中执行,
    }

-》requstBind

 protected void requestRebind() {
        if (mContainingBinding != null) {
            mContainingBinding.requestRebind();
        } else {
            synchronized (this) {
                if (mPendingRebind) {   //如果已经发出,就不在发出
                    return;
                }
                mPendingRebind = true;
            }
            if (mLifecycleOwner != null) {
                Lifecycle.State state = mLifecycleOwner.getLifecycle().getCurrentState();
                if (!state.isAtLeast(Lifecycle.State.STARTED)) {
                    return; // wait until lifecycle owner is started
                }
            }
            if (USE_CHOREOGRAPHER) {
	//请求同步信号,并添加回调,再下一次刷新的时候,执行绑定操作
                mChoreographer.postFrameCallback(mFrameCallback);
            } else {
                mUIThreadHandler.post(mRebindRunnable);
            }
        }
    }

-》mFrameCallback.run  //内部不再分析,就是调用runable.run

-》     mRebindRunnable.run()

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

            executePendingBindings();//会执行这个方法
        }
    };

-》executeBindingsInternal();

 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) {
            executeBindings();                              //执行绑定,由子类实现
            if (mRebindCallbacks != null) {
                mRebindCallbacks.notifyCallbacks(this, REBOUND, null);
            }
        }
        mIsExecutingPendingBindings = false;
    }

-》   executeBindings();    有回调了开始,再内部判断flag值,决定是否更新,如果变脏,就更新,更新比较合理,只更新变脏的数据
 

  protected void executeBindings() {
        long dirtyFlags = 0;
        synchronized(this) {
            dirtyFlags = mDirtyFlags;
            mDirtyFlags = 0;
        }
        java.lang.String modelInputGet = null;
        android.view.View.OnClickListener modelSubmitAndroidViewViewOnClickListener = null;
        com.daodian8.store.mine.ui.activity.RechargeAndDeductActivity model = mModel;
        android.databinding.ObservableField<java.lang.String> modelInput = null;

        if ((dirtyFlags & 0x7L) != 0) {//根据flag判断


            if ((dirtyFlags & 0x6L) != 0) {//设置监听

                    if (model != null) {
                        // read model::submit
                        modelSubmitAndroidViewViewOnClickListener = (((mModelSubmitAndroidViewViewOnClickListener == null) ? (mModelSubmitAndroidViewViewOnClickListener = new OnClickListenerImpl()) : mModelSubmitAndroidViewViewOnClickListener).setValue(model));
                    }
            }

                if (model != null) {
                    // read model.input
                    modelInput = model.input;
                }
                updateRegistration(0, modelInput);//这里是我们即将重点分析的,可监听对象
                //刷新数据的流程


                if (modelInput != null) {
                    // read model.input.get()
                    modelInputGet = modelInput.get();
                }
        }
        // batch finished
        if ((dirtyFlags & 0x7L) != 0) {  //判断当前的对应的属性是否是脏数据,如果是,更新
            // api target 1

            android.databinding.adapters.TextViewBindingAdapter.setText(this.etNickName, modelInputGet);
        }
        if ((dirtyFlags & 0x4L) != 0) {
            // api target 1

            android.databinding.adapters.TextViewBindingAdapter.setTextWatcher(this.etNickName, (android.databinding.adapters.TextViewBindingAdapter.BeforeTextChanged)null, (android.databinding.adapters.TextViewBindingAdapter.OnTextChanged)null, (android.databinding.adapters.TextViewBindingAdapter.AfterTextChanged)null, etNickNameandroidTextAttrChanged);
        }
        if ((dirtyFlags & 0x6L) != 0) {
            // api target 1

            this.tvSubmit.setOnClickListener(modelSubmitAndroidViewViewOnClickListener);
        }
    }

上面的一个设置普通数据,普通数据重新绑定,从设置数据,到数据绑定的流程分析完了。

以上分析得出,我们每次为布局设置数据,都会自动执行重新绑定,只是,会等到下次刷新
如果我们想要立即绑定,可以使用executePendingBindings()这里是立即绑定

为布局中设置的每一个(直接)数据,都有对应的属性id,也都对应一个变脏的flag

再数据变化的时候,根据属性id,通知更新,再绑定数据的时候,根据变脏的flag 刷新对应的数据。

 

下面我们分析,对于可监听的数据,再数据变化之后,更新数据的流程

//再这里,对于可监听的数,就是实现了Obserable,会注册到父类中,执行
      updateRegistration(0, modelInput);  //前面的参数是本地的FieldId,后面是可监听的数据,

-》 updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);

updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
    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;
        }
        if (listener.getTarget() == observable) {
            return false;//nothing to do, same object
        }
        unregisterFrom(localFieldId);
        registerTo(localFieldId, observable, listenerCreator);
        return true;
    }

-》     registerTo(localFieldId, observable, listenerCreator);  //第一次,注册

  protected void registerTo(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
        if (observable == null) {
            return;
        }
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            listener = listenerCreator.create(this, localFieldId);//创建listener,
            mLocalFieldObservers[localFieldId] = listener;//保存起来
            if (mLifecycleOwner != null) {
                listener.setLifecycleOwner(mLifecycleOwner);  //如果有lifeCycleOwner,同时感知生命周期
            }
        }
        listener.setTarget(observable);   //设置被观察对象,
    }

下面我们分析WeakListener      和创建的他的CreateWeakListener

对于不同的被监听数据类型,有不同的WeakListener   的实现

对于普通属性(非集合,并且实现了Obserable)我们使用的实现类是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);  //返回创建的listener  ,内部持有了WeakPropertyListener 
        }

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

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

//下面是创建的Listener
  //本类,是继承弱引用的,持有的DataBinding也是弱引用,所有DataBinding不会内存泄漏

 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) {       //注册的时候,把tag设置进来,被监听对象
            unregister();
            mTarget = object;
            if (mTarget != null) {
  //由  WeakPropertyListener 来监听,再数据变化的时候执行WeakPropertyListener .onPropertyChanged(Observable sender, int propertyId)
                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) {         //如果binder已经被销毁了,就注销listener
                unregister(); // The binder is dead
            }
            return binder;
        }
    }

//弱监听的创建者
    private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
        }
    };

下面分析数据变化的时候执行的方法

WeakPropertyListener .onPropertyChanged

  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);//否者就调用对应binder的属性变化方法
        }

 -》binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);

 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;
        }
	//询问子类,这个属性是否变化,如果变化了,下面就要申请重新绑定就是刷新,这个方法由子Databind,实现
        boolean result = onFieldChange(mLocalFieldId, object, fieldId);  
        if (result) {
            requestRebind();//请求刷新数据,和我们一开始分析的流程一样
        }
    }

对于可监听数据,更新的流程,就是以上的流程。

 

对于双向绑定,没什莫特殊的地方,我们平时自定义双向的绑定逻辑一样


Databing双向绑定的逻辑

监听EditText数据的变化----数据变化后,设置到对应的数据对象,--------然后对应的数据监听对象-----会导致下一次的刷新,
但是再数据数据的时候,会判断,当前要更新的数据和editeText显示的数据,如果相等,如果相等,就不会设置新的数据,否者,
会导致,递归刷新,导致栈溢出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值