序
在上一篇博客,我们是通过DataBindingUtil的.setContentView(this, R.layout.activity_main)方法来获取DataBinding对象的。那这个继承ViewDataBinding的Databinding对象是什么?它在整个架构中起到的作用是什么?the binding adapter什么时候调用setText()方法来设置text属性或者是调用setOnClickListener()方法来对点击事件添加一个监听?数据驱动具体是怎么回事儿?我们带着问题去相关的源码里面找一找答案。
ViewDataBinding类的一些内部类和方法
接口ObservableReference包含一些控制Listener和生命周期的操作,封装和定义了如下四个操作:
private interface ObservableReference<T> {
WeakListener<T> getListener();
void addListener(T target);
void removeListener(T target);
void setLifecycleOwner(LifecycleOwner lifecycleOwner);
}
看几个重要的类:首先是静态内部类WeakListener里面定义了一个ObservableReference变量和int类型的绑定id和T类型的Observable,也是继承ViewDataBinding的引用——在当前类中有多个这种引用——class ViewDataBinding extends BaseObservable extends Observable。后面定义的WeakPropertyListener,WeakListListener,WeakMapListener,LiveDataListener都是针对具体情况的二次定义/实现:
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;
}
}
再看一下类WeakProPertyListener——The callback that is called by Observable when an observable property has changed
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) {
}
@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);
}
}
那我们看一个属性绑定的静态实现类——继承”属性改变时候的回调方法的类”同时实现了”ObservableReference”接口。其中定义了一个WeakListener对象是根据ViewDataBinding对象和localFieldId和它本身(因为是实现了接口ObservableReference)来创建的,既然实现了接口我们看一下重写的那些方法可以发现getListener返回了构造函数创建的weakListener,addListener做的是将传入进来的Observable调用addPropertyChangedCallback,removeListener是observable调用自己的移除PropertyChangedCallback方法;换句话说这个接口WeakListener是定义了Observable Object触发View objects的功能封装。那这个WeakPropertyListener就是对于Observable的属性变化的时候的回调行为是binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId)。
具体看下WeakListener的setTarget(T object)和unregister():
WeakListener<T> extends WeakReference<ViewDataBinding>
public void setTarget(T object) {
unregister();
mTarget = object;
if (mTarget != null) {
mObservable.addListener(mTarget);
}
}
WeakProPertyListener extends Observable.OnPropertyChangedCallback implements ObservableReference<Observable>
@Override
public void addListener(Observable target) {
target.addOnPropertyChangedCallback(this);
}
相当于 WeakListener<T> setTarget(T object) --> object.addOnPropertyChangedCallback(this);
public boolean unregister() {
boolean unregistered = false;
if (mTarget != null) {
mObservable.removeListener(mTarget);
unregistered = true;
}
mTarget = null;
return unregistered;
}
@Override
public void removeListener(Observable target) {
target.removeOnPropertyChangedCallback(this);
}
相当于 WeakListener<T> unregister() --> object.removeOnPropertyChangedCallback(this);
其他数据结构的Listener,其实和WeakPropertyListener差不多,就是回调的方式有些不同。一些相同的方法就用省略号代替了:
private static class WeakListListener extends ObservableList.OnListChangedCallback
implements ObservableReference<ObservableList> {
final WeakListener<ObservableList> mListener;
public WeakListListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener<ObservableList>(binder, localFieldId, this);
}
...
@Override
public void onChanged(ObservableList sender) {
ViewDataBinding binder = mListener.getBinder();
if (binder == null) {
return;
}
ObservableList target = mListener.getTarget();
if (target != sender) {
return; // We expect notifications only from sender
}
binder.handleFieldChange(mListener.mLocalFieldId, target, 0);
}
@Override
public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition,
int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
}
private static class WeakMapListener extends ObservableMap.OnMapChangedCallback
implements ObservableReference<ObservableMap> {
final WeakListener<ObservableMap> mListener;
public WeakMapListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener<ObservableMap>(binder, localFieldId, this);
}
...
@Override
public void onMapChanged(ObservableMap sender, Object key) {
ViewDataBinding binder = mListener.getBinder();
if (binder == null || sender != mListener.getTarget()) {
return;
}
binder.handleFieldChange(mListener.mLocalFieldId, sender, 0);
}
}
private static class LiveDataListener implements Observer,
ObservableReference<LiveData<?>> {
final WeakListener<LiveData<?>> mListener;
LifecycleOwner mLifecycleOwner;
public LiveDataListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener(binder, localFieldId, this);
}
...
@Override
public void onChanged(@Nullable Object o) {
ViewDataBinding binder = mListener.getBinder();
binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
}
}
Observable的属性变化的时候的回调具体来看一下:
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();
}
}
接着我们看一下我上一篇博客的demo中登录页面实现里的ViewDataBinding类的子类是怎么实现onFieldChange方法的:
@Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
case 0 :
return onChangeUserName((android.databinding.ObservableField<java.lang.String>) object, fieldId);
case 1 :
return onChangeUserFormatOk((android.databinding.ObservableBoolean) object, fieldId);
case 2 :
return onChangeUserRememberPsw((android.databinding.ObservableBoolean) object, fieldId);
case 3 :
return onChangeUserPassword((android.databinding.ObservableField<java.lang.String>) object, fieldId);
case 4 :
return onChangeUserErrorNameTips((android.databinding.ObservableField<java.lang.String>) object, fieldId);
case 5 :
return onChangeUserErrorPswTips((android.databinding.ObservableField<java.lang.String>) object, fieldId);
}
return false;
}
private boolean onChangeUserName(android.databinding.ObservableField<java.lang.String> UserName, int fieldId) {
if (fieldId == BR._all) {
synchronized(this) {
mDirtyFlags |= 0x1L; ###### 0->1
}
return true;
}
return false;
}
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);
}
}
}
主要是运行抽象方法onFieldChange(int localFieldId, Object object, int fieldId)将mDirtyFlags进行运算之后重新绑定。如果是自布局included Binding Layout就调用它的requestRebind方法,如果不是就在下一帧运行重新绑定任务了。应该是要刷新对应的UI了吖?。?+ !。!感觉这里除了mDirtyFlags改变了有些可疑!有可能是刷新UI去了其他都是“常规操作”啊!。!而且从来没有出现过控件的什么代码啊?。!天了噜!不急!我们大致先了解了这几个类,再去ViewDataBinding类找找。
首先是构造函数:
protected ViewDataBinding(DataBindingComponent bindingComponent, View root, int localFieldCount) {
mBindingComponent = bindingComponent;
mLocalFieldObservers = new WeakListener[localFieldCount];
this.mRoot = root;
if (Looper.myLooper() == null) {
throw new IllegalStateException("DataBinding must be created in view's UI Thread");
}
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());
}
}
然后发现了静态块:
private static final OnAttachStateChangeListener 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);
binding.mRebindRunnable.run();
v.removeOnAttachStateChangeListener(this);
}
@Override
public void onViewDetachedFromWindow(View v) {
}
};
}
}
他会设置一个监听,在页面和窗口绑定之后从rootView里面取到当前的ViewDataBinding对象,调用里面的RebindRunnable。
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();
}
};
这个Runnable主要是将待重新绑定状态mPendingRebind赋值为false,移除队列中所有绑定关系,运行待绑定的任务。
//将ViewDatabinding的队列清空,将里面的对于对象field in Model Obj的监听都移除
private static void processReferenceQueue() {
Reference<? extends ViewDataBinding> ref;
while ((ref = sReferenceQueue.poll()) != null) {
if (ref instanceof WeakListener) {
WeakListener listener = (WeakListener) ref;
listener.unregister();
}
}
}
/*mContainingBinding是对于有include布局ViewDataBinding对象的绑定对象,如果有的话需要运行他自己的executePendingBindings方法否则运行executeBindingsInternal方法,最后运行的是抽象方法executeBindings,在这个方法里面主要是将Observable Obj和他们的value清空,将绑定的那个对象赋值到这里,然后根据dirtyFlags和唯一的标识位将每一个Observable的关系都绑定好。*/
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) {
executeBindings();
if (mRebindCallbacks != null) {
mRebindCallbacks.notifyCallbacks(this, REBOUND, null);
}
}
mIsExecutingPendingBindings = false;
}
具体看下登录页面实现里的ViewDataBinding类的子类是怎么实现一个绑定方法的。
将Observable Obj和他们的value清空,将绑定的那个对象赋值到这里,然后调用updateRegistration方法:
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
java.lang.String userPasswordGet = null;
android.databinding.ObservableField<java.lang.String> userName = null;
java.lang.String userErrorNameTipsGet = null;
org.zy.demonew.twoway.action.LoginAction login = mLogin;
android.databinding.adapters.TextViewBindingAdapter.AfterTextChanged userAfterTextChangeAndroidDatabindingAdaptersTextViewBindingAdapterAfterTextChanged = null;
android.databinding.ObservableBoolean userFormatOk = null;
java.lang.String userNameGet = null;
android.databinding.ObservableBoolean userRememberPsw = null;
boolean userFormatOkGet = false;
java.lang.String userErrorPswTipsGet = null;
android.databinding.ObservableField<java.lang.String> userPassword = null;
boolean userRememberPswGet = false;
org.zy.demonew.twoway.model.User user = mUser;
android.databinding.ObservableField<java.lang.String> userErrorNameTips = null;
android.databinding.ObservableField<java.lang.String> userErrorPswTips = null;
if ((dirtyFlags & 0x1bfL) != 0) {
if ((dirtyFlags & 0x181L) != 0) { ###### 448
if (user != null) {
// read user.name
userName = user.name;
}
updateRegistration(0, userName);
if (userName != null) {
// read user.name.get()
userNameGet = userName.get();
}
}
if ((dirtyFlags & 0x180L) != 0) {
......
}
看一下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;
}
if (listener.getTarget() == observable) {
return false;//nothing to do, same object
}
unregisterFrom(localFieldId);
registerTo(localFieldId, observable, listenerCreator);
return true;
}
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
}
};
protected boolean updateRegistration(int localFieldId, Observable observable) {
return 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;
}
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);
mLocalFieldObservers[localFieldId] = listener;
if (mLifecycleOwner != null) {
listener.setLifecycleOwner(mLifecycleOwner);
}
}
listener.setTarget(observable);
}
mLocalFieldObservers用来存储WeakListener的数组,这个方法是根据你的localFieldId和对应的CreateWeakListener来创建WeakListener,并将Observable对象添加属性变化的监听,属性变化的时候能调用onPropertyChange方法,然后调用binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId)方法,然后是onFieldChange方法…
哇,果然漏了!在省略号里面,在方法executeBindings里面除了更新绑定关系和用新的对象赋值,还有根据dirtyFlags对控件进行对应处理。比如我在省略号下面的代码:
......
// batch finished
if ((dirtyFlags & 0x19L) != 0) {
// api target 1
android.databinding.adapters.TextViewBindingAdapter.setText(this.mboundView1, userFirstNameGet);
}
if ((dirtyFlags & 0x1cL) != 0) {
// api target 1
android.databinding.adapters.TextViewBindingAdapter.setText(this.mboundView2, userLastNameGet);
}
if ((dirtyFlags & 0x1aL) != 0) {
// api target 1
android.databinding.adapters.TextViewBindingAdapter.setText(this.mboundView3, mboundView3AndroidStringAgeFormatUserAge);
}
也就是这个方法分成两块,一块是对数据更新和绑定关系更新还有就是对控件操作。
注意点
1. 实例化的DataBinding包含的一些绑定的布局:protected static class IncludedLayouts
2. BaseObservableField继承BaseObservable类主要有四个方法addOnPropertyChangedCallback(@NonNull OnPropertyChangedCallback callback) ;removeOnPropertyChangedCallback(@NonNull OnPropertyChangedCallback callback); notifyChange();notifyPropertyChanged(int fieldId)
3. fieldId是model用Bindable注释的变量的唯一标识,在自动生成的BR文件中
4. mLocalFieldId也是系统生成的,从0开始到最后一个绑定关系结束
5. 当dirtyFlag改变的时候只有对应的属性进行了重新绑定,其他地方不需要进行重新绑定
跋
在MVVM中最重要的VM层是由安卓系统提供的工具帮我们生成和维护的,官方出品必出精品,完全放心使用。通过VM层对dirtyFlags进行与运算然后重新binding再根据新的dirtyFlags来控制执行相应的V层和M层的方法实现双向绑定。我们只要维护好我们的V层和M层就可以了,大大提高了开发效率和减少了代码量,结构上也清晰了很多。
本文原创,转载请注明链接https://blog.csdn.net/zhangwude2301
Demo下载地址