再编译期,使用注解处理器生成对应的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 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 {
final WeakListener mListener;
public WeakPropertyListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener(binder, localFieldId, this); //返回创建的listener ,内部持有了WeakPropertyListener
}
@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);
}
}
//下面是创建的Listener
//本类,是继承弱引用的,持有的DataBinding也是弱引用,所有DataBinding不会内存泄漏
private static class WeakListener extends WeakReference {
private final ObservableReference mObservable;
protected final int mLocalFieldId;
private T mTarget;
public WeakListener(ViewDataBinding binder, int localFieldId,
ObservableReference 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显示的数据,如果相等,如果相等,就不会设置新的数据,否者,
会导致,递归刷新,导致栈溢出