AndroidX设计架构MVVM之DataBinding3.5.1结合LiveData2.1.0的分析
原文
AndroidX设计架构MVVM之ViewModel创建流程原理分析
AndroidX设计架构MVVM之ViewModel生命周期分析
AndroidX设计架构MVVM之LiveDatal生命周期及数据监听分析
AndroidX设计架构MVVM之DataBinding搭配LiveData的分析
AndroidX设计架构MVVM之DataBinding+ViewModel+LiveData
本文只分析DataBinding结合LiveData对比原有的ObserveableField的共同点和区别,不做详细使用说明
LiveData部分的分析请参考LiveDatal生命周期及数据监听分析,设计到LiveData这部分的会在注释中标识。
首先看一下代码中绑定数据的入口,这些都是编译过程中DataDinding自动生成的。
//DataBinding 动态绑定,属性为ObserveableField
public void setUserNoLive(@Nullable com.lyldding.modulemvvm.bean.UserNoLiveBean UserNoLive) {
this.mUserNoLive = UserNoLive;
synchronized(this) {
mDirtyFlags |= 0x8L;
}
//通知观察者
notifyPropertyChanged(BR.userNoLive);
//分析点1
super.requestRebind();
}
//ViewModel + LiveData模式
public void setVMUser(@Nullable com.lyldding.modulemvvm.viewmodel.VMUser VMUser) {
this.mVMUser = VMUser;
synchronized(this) {
mDirtyFlags |= 0x10L;
}
//通知观察者
notifyPropertyChanged(BR.vMUser);
//分析点1
super.requestRebind();
}
分析点1:requestRebind()主要执行View的数据绑定,如果设置有生命周期的话,判断处于非【onStart,onPause】区间则直接返回(那么在onCreate中更新数据,什么时机绑定数据呢?这一点文章结尾处分析)。这部分走正常流程,没有设置生命周期的监听。
protected void requestRebind() {
// 如果View中有include 的view,也需要执行绑定数据
if (mContainingBinding != null) {
mContainingBinding.requestRebind();
} else {
final LifecycleOwner owner = this.mLifecycleOwner;
//LifecycleOwner 不为空则判断View的状态
//不为STARTED直接返回
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;
}
//SDK_INT >= 16,则在下一帧运行,最终执行的都是mRebindRunnable
if (USE_CHOREOGRAPHER) {
mChoreographer.postFrameCallback(mFrameCallback);
} else {
//分析点2
mUIThreadHandler.post(mRebindRunnable);
}
}
}
//mFrameCallback 示例
mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
//分析点2
mRebindRunnable.run();
}
};
分析点2:mRebindRunnable()先移除所有的观察者,然后再加观察者并绑定数据。
private final Runnable mRebindRunnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
mPendingRebind = false;
}
//移除所有的观察者
processReferenceQueue();
//sdk >=19,判断view是否附加到窗口,如果没有就设置监听,
//当附加到窗口后,再执行一遍mRebindRunnable
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;
}
}
//分析点3
executePendingBindings();
}
};
分析点3:没什么特别,最终执行到 executeBindings();
public void executePendingBindings() {
if (mContainingBinding == null) {
executeBindingsInternal();
} else {
mContainingBinding.executePendingBindings();
}
}
private void executeBindingsInternal() {
//如果上一次没有执行结束,则本次的数据绑定则一直循环等待
if (mIsExecutingPendingBindings) {
requestRebind();
return;
}
if (!hasPendingBindings()) {
return;
}
mIsExecutingPendingBindings = true;
mRebindHalted = false;
//这里没有添加Rebind的回调,所以为空
if (mRebindCallbacks != null) {
mRebindCallbacks.notifyCallbacks(this, REBIND, null);
// The onRebindListeners will change mPendingHalted
if (mRebindHalted) {
mRebindCallbacks.notifyCallbacks(this, HALTED, null);
}
}
if (!mRebindHalted) {
//分析点4
executeBindings();
if (mRebindCallbacks != null) {
mRebindCallbacks.notifyCallbacks(this, REBOUND, null);
}
}
mIsExecutingPendingBindings = false;
}
分析点4:主要的工作为设置点击事件的监听,更新注册数据的观察者,绑定view展示的数据。
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
androidx.databinding.ObservableField<java.lang.String> userNoLiveName = null;
java.lang.String vMUserUserInfoAge = null;
com.lyldding.modulemvvm.MvvmMainActivity eventListener = mEventListener;
com.lyldding.modulemvvm.bean.UserBean vMUserUserInfoGetValue = null;
com.lyldding.modulemvvm.bean.UserNoLiveBean userNoLive = mUserNoLive;
androidx.lifecycle.MutableLiveData<com.lyldding.modulemvvm.bean.UserBean> vMUserUserInfo = null;
com.lyldding.modulemvvm.viewmodel.VMUser vMUser = mVMUser;
java.lang.String vMUserUserInfoName = null;
android.view.View.OnClickListener eventListenerOnClickAndroidViewViewOnClickListener = null;
java.lang.String userNoLiveNameGet = null;
if ((dirtyFlags & 0x24L) != 0) {
//分析点5
//点击事件不为空则设置点击事件,
if (eventListener != null) {
// read eventListener::onClick
eventListenerOnClickAndroidViewViewOnClickListener = (((mEventListenerOnClickAndroidViewViewOnClickListener == null) ? (mEventListenerOnClickAndroidViewViewOnClickListener = new OnClickListenerImpl()) : mEventListenerOnClickAndroidViewViewOnClickListener).setValue(eventListener));
}
}
if ((dirtyFlags & 0x29L) != 0) {
if (userNoLive != null) {
// read userNoLive.name
userNoLiveName = userNoLive.name;
}
//分析点6 更新观察者
//这里是数据对象的ObservableField类属性
//如果有多个ObservableField类属性的话,会生成多个updateRegistration(localFieldId, userNoLiveXXX);
updateRegistration(0, userNoLiveName);
if (userNoLiveName != null) {
// read userNoLive.name.get()
userNoLiveNameGet = userNoLiveName.get();
}
}
if ((dirtyFlags & 0x32L) != 0) {
if (vMUser != null) {
// read vMUser.userInfo
vMUserUserInfo = vMUser.getUserInfo();
}
//分析点7 更新观察者
//这里是LiveData数据对象
updateLiveDataRegistration(1, vMUserUserInfo);
if (vMUserUserInfo != null) {
// read vMUser.userInfo.getValue()
vMUserUserInfoGetValue = vMUserUserInfo.getValue();
}
if (vMUserUserInfoGetValue != null) {
// read vMUser.userInfo.getValue().age
vMUserUserInfoAge = vMUserUserInfoGetValue.getAge();
// read vMUser.userInfo.getValue().name
vMUserUserInfoName = vMUserUserInfoGetValue.getName();
}
}
// batch finished
if ((dirtyFlags & 0x32L) != 0) {
// api target 1
//设置View展示数据
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.age, vMUserUserInfoAge);
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.name, vMUserUserInfoName);
}
if ((dirtyFlags & 0x29L) != 0) {
// api target 1
//设置View展示数据
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.nameNoLive, userNoLiveNameGet);
}
if ((dirtyFlags & 0x24L) != 0) {
// api target 1
//设置点击事件监听
this.title.setOnClickListener(eventListenerOnClickAndroidViewViewOnClickListener);
}
}
分析点5:其实就对原有对象的的public 点击方法进行了包装转化。
// Listener Stub Implementations
public static class OnClickListenerImpl implements android.view.View.OnClickListener{
private com.lyldding.modulemvvm.MvvmMainActivity value;
public OnClickListenerImpl setValue(com.lyldding.modulemvvm.MvvmMainActivity value) {
this.value = value;
return value == null ? null : this;
}
@Override
public void onClick(android.view.View arg0) {
//真正执行的地方
this.value.onClick(arg0);
}
}
分析点6和分析点7:这部分就是ObservableField和LiveData区别的开始,注意传入的方法字段类型不一样,不过流程相似的。下面就对比着把流程走完。
/**
* @hide
*/
//ObservableField 传入的字段为Observable
protected boolean updateRegistration(int localFieldId, Observable observable) {
//分析点8
return updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
}
/**
* @hide
*/
//LiveData 传入的字段为Observable LiveData
protected boolean updateLiveDataRegistration(int localFieldId, LiveData<?> observable) {
mInLiveDataRegisterObserver = true;
try {
//分析点9
return updateRegistration(localFieldId, observable, CREATE_LIVE_DATA_LISTENER);
} finally {
mInLiveDataRegisterObserver = false;
}
}
分析点8和分析点9:也就是CREATE_PROPERTY_LISTENER和CREATE_LIVE_DATA_LISTENER的区别。接下来先看两个CREATE_XXXX的区别,在分析updateRegistration();
两个CREATE_XXXX的区别:只是创建类不同
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
//分析点10 WeakPropertyListener
return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
}
};
private static final CreateWeakListener CREATE_LIVE_DATA_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
//分析点11 LiveDataListener
return new LiveDataListener(viewDataBinding, localFieldId).getListener();
}
};
updateRegistration():unregisterFrom先注销原有观察者,registerTo再注册一个当前的观察者。
//
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);
//注册观察者
//分析点12,这部分放到下面
registerTo(localFieldId, observable, listenerCreator);
return true;
}
分析点10和分析点11:也就是WeakPropertyListener和LiveDataListener的区别。注意接口ObservableReference传入的泛型类型,接下来分别分析一下两个类
WeakPropertyListener
private static class WeakPropertyListener extends Observable.OnPropertyChangedCallback
implements ObservableReference<Observable> {
final WeakListener<Observable> mListener;
public WeakPropertyListener(ViewDataBinding binder, int localFieldId) {
//分析点13 创建一个WeakListener
mListener = new WeakListener<Observable>(binder, localFieldId, this);
}
@Override
//返回WeakListener
public WeakListener<Observable> getListener() {
return mListener;
}
@Override
//这个地方要注意,下文会提到
public void addListener(Observable target) {
//ObservableField添加数据属性变化的监听
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?
}
//view重新绑定当前属性值
binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
}
}
//view重新绑定当前属性值
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) {
//view重新绑定当前属性值
//忘记的返回查看分析点1
requestRebind();
}
}
LiveDataListener:这个类中能看到单独使用LiveData时候的影子,不熟悉的话请参考LiveDatal生命周期及数据监听分析
private static class LiveDataListener implements Observer,
ObservableReference<LiveData<?>> {
final WeakListener<LiveData<?>> mListener;
LifecycleOwner mLifecycleOwner;
public LiveDataListener(ViewDataBinding binder, int localFieldId) {
//分析点13 创建一个WeakListener
mListener = new WeakListener(binder, localFieldId, this);
}
@Override
//这个地方要注意,下文会提到
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
LifecycleOwner owner = (LifecycleOwner) lifecycleOwner;
LiveData<?> liveData = mListener.getTarget();
if (liveData != null) {
if (mLifecycleOwner != null) {
//移除观察者
liveData.removeObserver(this);
}
if (lifecycleOwner != null) {
//添加生命周期观察者,并监听数据变化
liveData.observe(owner, this);
}
}
mLifecycleOwner = owner;
}
@Override
//返回WeakListener
public WeakListener<LiveData<?>> getListener() {
return mListener;
}
@Override
//这个地方要注意,下文会提到
public void addListener(LiveData<?> target) {
if (mLifecycleOwner != null) {
//livedata添加生命周期观察者,并监听数据变化
target.observe(mLifecycleOwner, this);
}
}
@Override
public void removeListener(LiveData<?> target) {
target.removeObserver(this);
}
@Override
//LiveData 数据变化时的回调
public void onChanged(@Nullable Object o) {
ViewDataBinding binder = mListener.getBinder();
if (binder != null) {
//view重新绑定当前属性值
binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
}
}
}
//view重新绑定当前属性值
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) {
//view重新绑定当前属性值
//忘记的返回查看分析点1
requestRebind();
}
}
分析点13:看一下WeakListener到底是什么?WeakListener继承WeakReference,其实就是一个弱引用类,持有一个实现ObservableReference接口对象observable,并提供设置LifecycleOwner和监听的方法。
private static class WeakListener<T> extends WeakReference<ViewDataBinding> {
private final ObservableReference<T> mObservable;
protected final int mLocalFieldId;
private T mTarget;
//构造函数传入的有ViewDataBinding ,属性FieldId,
//一个实现ObservableReference接口对象observable
public WeakListener(ViewDataBinding binder, int localFieldId,
ObservableReference<T> observable) {
super(binder, sReferenceQueue);
mLocalFieldId = localFieldId;
mObservable = observable;
}
//WeakListener 设置LifecycleOwner
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
//ObservableField 和LiveData类型的实现方式不一样
//可以回看分析点10 和分析点11
mObservable.setLifecycleOwner(lifecycleOwner);
}
//注册
//这个地方要注意,下文会提到
public void setTarget(T object) {
unregister();
mTarget = object;
if (mTarget != null) {
//ObservableField 和LiveData类型的实现方式不一样
//可以回看分析点10 和分析点11
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;
}
}
分析点12:上面的准备工作都分析了,分析点8和9创建了CreateWeakListener,在这部分创建一个WeakListener对象(见分析点13),
protected void registerTo(int localFieldId, Object observable,
CreateWeakListener listenerCreator) {
if (observable == null) {
return;
}
WeakListener listener = mLocalFieldObservers[localFieldId];
if (listener == null) {
//创建WeakListener,
listener = listenerCreator.create(this, localFieldId);
mLocalFieldObservers[localFieldId] = listener;
if (mLifecycleOwner != null) {
//WeakListener的setLifecycleOwner
//可以回看分析点13
listener.setLifecycleOwner(mLifecycleOwner);
}
}
//注册观察者
//WeakListener的setTarget,让持有的对象注册观察者
//可以回看分析点13
listener.setTarget(observable);
}
到此:DataBinding中对使用ObservableField和LiveData类型的数据动态绑定更新就结束。
分析点1:遗留问题,假如Databinding 设置了LifecycleOwner ,那么在onCreate中更新数据,什么时机绑定数据呢?
这时候就在OnStart中绑定数据
解铃还须系铃人,看ViewDataBinding的setLifecycleOwner方法。
@MainThread
public void setLifecycleOwner(@Nullable LifecycleOwner lifecycleOwner) {
if (mLifecycleOwner == lifecycleOwner) {
return;
}
//移除mOnStartListener观察者
if (mLifecycleOwner != null) {
mLifecycleOwner.getLifecycle().removeObserver(mOnStartListener);
}
mLifecycleOwner = lifecycleOwner;
if (lifecycleOwner != null) {
if (mOnStartListener == null) {
//这里创建mOnStartListener观察者
mOnStartListener = new OnStartListener(this);
}
//添加mOnStartListener观察者
lifecycleOwner.getLifecycle().addObserver(mOnStartListener);
}
for (WeakListener<?> weakListener : mLocalFieldObservers) {
if (weakListener != null) {
//可以回看分析点13
weakListener.setLifecycleOwner(lifecycleOwner);
}
}
}
static class OnStartListener implements LifecycleObserver {
final WeakReference<ViewDataBinding> mBinding;
private OnStartListener(ViewDataBinding binding) {
//创建binder的弱引用
mBinding = new WeakReference<>(binding);
}
//在view的生命周期为onStart中回调
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
ViewDataBinding dataBinding = mBinding.get();
if (dataBinding != null) {
//执行数据绑定
//可以回看分析点3
dataBinding.executePendingBindings();
}
}
}
总结:从上面的分析可知,在使用BindingImpl设置绑定ViewModel数据时,会执行executeBindings(),executeBindings()中会注册一个数据变化的观察者observer并且更新view中的数据,每当数据发生变化时(ObservableField.xx.set() 和LiveData.setValue),都会回调observer的方法,进而重新执行executeBindings()。