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()。