日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android的DataBinding原理介绍

發(fā)布時(shí)間:2024/4/14 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android的DataBinding原理介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Activity在inflate layout時(shí),通過DataBindingUtil來生成綁定,從代碼看,是遍歷contentView得到View數(shù)組對(duì)象,然后通過數(shù)據(jù)綁定library生成對(duì)應(yīng)的Binding類,含Views、變量、listeners等。生成類位于
build/intermediates/classes/debug/…package…/databinding/xxx.Java?下,具體如何生成這里暫不作深入。

綁定過程

  • 首先,會(huì)在父類(ViewDataBinding)中實(shí)例化回調(diào)或Handler,用于之后的綁定操作;
private static final boolean USE_CHOREOGRAPHER = SDK_INT >= 16;

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());
}
  • 接著,通過調(diào)用 mapBindings(…) 遍歷布局以獲得包含bound、includes、ID Views的數(shù)組對(duì)象,再依次賦給對(duì)應(yīng)View
final Object[] bindings = mapBindings(bindingComponent, root, 3, sIncludes, sViewsWithIds);
this.mboundView0 = (Android.widget.LinearLayout) bindings[0];
this.mboundView0.setTag(null);
  • 然后,調(diào)用 invalidateAll() -> requestRebind() -> … -> mRebindRunnable.run() – 執(zhí)行 Runnable
// 用于動(dòng)態(tài)重新綁定 Views
private final Runnable mRebindRunnable = new Runnable() {
? ?
@Override
? ?
public void run() {
? ? ? ?
synchronized (this) {
? ? ? ? ? ? mPendingRebind
= false;
? ? ? ?
}
? ? ? ?
.....
? ? ? ? executePendingBindings
();
? ?
}
};
  • 最后,通過該Runnable會(huì)執(zhí)行到 executePendingBindings() -> … -> executeBindings(),在這里會(huì)執(zhí)行綁定相關(guān)操作。
@Override
protected void executeBindings() {
? ?
long dirtyFlags = 0;
? ?
synchronized(this) {
? ? ? ? dirtyFlags
= mDirtyFlags; ? // mDirtyFlags 變量更新的標(biāo)志
? ? ? ? mDirtyFlags
= 0;
? ?
}
? ?
.....
}

設(shè)置變量(數(shù)據(jù)對(duì)象)

普通?Java?bean 對(duì)象

  • 首先,通過mDirtyFlags標(biāo)識(shí)變量(所有變量共用)
synchronized(this) {
? ? mDirtyFlags
|= 0x1L;
}
  • 然后,調(diào)用 notifyPropertyChanged(…) 來通知更新(若有回調(diào))
public void notifyPropertyChanged(int fieldId) {
? ?
if (mCallbacks != null) {
? ? ? ? mCallbacks
.notifyCallbacks(this, fieldId, null);
? ?
}
}
  • 最后,調(diào)用 requestRebind() -> … -> executeBindings() 再次執(zhí)行綁定操作,將數(shù)據(jù)更新到Views上
@Override
protected void executeBindings() {
? ?
long dirtyFlags = 0;
? ?
synchronized(this) {
? ? ? ? dirtyFlags
= mDirtyFlags;
? ? ? ? mDirtyFlags
= 0;
? ?
}
? ?
.....
}

Observable 對(duì)象

  • 在設(shè)置變量時(shí),會(huì)先調(diào)用 updateRegistration(..) 注冊(cè)一個(gè)Observable對(duì)象的監(jiān)聽
public void setContact(com.connorlin.databinding.model.ObservableContact contact) {
? ? updateRegistration
(0, contact);
? ?
this.mContact = contact;
? ?
synchronized(this) {
? ? ? ? mDirtyFlags
|= 0x1L;
? ?
}
? ? notifyPropertyChanged
(BR.contact);
? ?
super.requestRebind();
}
  • 其他步驟同普通?Java?bean 對(duì)象

ObservableFields 對(duì)象

  • 前期步驟同普通?Java?Bean 對(duì)象
  • 與 Observable 對(duì)象不同的是,Observable對(duì)象的監(jiān)聽是在 executeBindings() 中注冊(cè)的
@Override
protected void executeBindings() {
? ?
long dirtyFlags = 0;
? ?
synchronized(this) {
? ? ? ? dirtyFlags
= mDirtyFlags;
? ? ? ? mDirtyFlags
= 0;
? ?
}
? ?
...
? ?
if ((dirtyFlags & 0xfL) != 0) {
? ? ? ?
if ((dirtyFlags & 0xdL) != 0) {
? ? ? ? ? ?
if (contact != null) {
? ? ? ? ? ? ? ?
// read contact.mName
? ? ? ? ? ? ? ? mNameContact
= contact.mName;
? ? ? ? ? ?
}
? ? ? ? ? ? updateRegistration
(0, mNameContact);

? ? ? ? ? ?
if (mNameContact != null) {
? ? ? ? ? ? ? ?
// read contact.mName.get()
? ? ? ? ? ? ? ? mNameContact1
= mNameContact.get();
? ? ? ? ? ?
}
? ? ? ?
}
? ? ? ?
...
? ?
}
? ?
...
}

注冊(cè)O(shè)bservable對(duì)象監(jiān)聽

  • 入口 updateRegistration(0, contact) :
protected boolean updateRegistration(int localFieldId, Observable observable) {
? ?
return updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
}

private boolean updateRegistration(int localFieldId, Object observable,
? ? ? ?
CreateWeakListener listenerCreator) {
? ?
...
? ?
// 確保不重復(fù)監(jiān)聽,先移除再添加觀察監(jiān)聽
? ? unregisterFrom
(localFieldId);
? ? registerTo
(localFieldId, observable, listenerCreator);
? ?
return true;
}

protected void registerTo(int localFieldId, Object observable,
? ? ? ?
CreateWeakListener listenerCreator) {
? ?
if (observable == null) {
? ? ? ?
return;
? ?
}

? ?
// 創(chuàng)建對(duì)象監(jiān)聽并存到mLocalFieldObservers中
? ?
WeakListener listener = mLocalFieldObservers[localFieldId];
? ?
if (listener == null) {
? ? ? ?
// CREATE_PROPERTY_LISTENER -> create(...)
? ? ? ? listener
= listenerCreator.create(this, localFieldId);
? ? ? ? mLocalFieldObservers
[localFieldId] = listener;
? ?
}

? ?
// 將監(jiān)聽綁定到Observable對(duì)象上
? ? listener
.setTarget(observable);
}

每個(gè)Observable對(duì)象都會(huì)添加一個(gè)觀察監(jiān)聽,保存在數(shù)組 mLocalFieldObservers 中,并以 localFieldId 索引。

  • CREATE_PROPERTY_LISTENER 為何物?
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
? ?
@Override
? ?
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
? ? ? ?
// 返回從WeakPropertyListener實(shí)例中獲取的監(jiān)聽器(WeakListener)
? ? ? ?
return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
? ?
}
}

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) {
? ? ? ?
// WeakPropertyListener 繼承于 Observable.OnPropertyChangedCallback,
? ? ? ?
// 所以 this 其實(shí)就是 Observable對(duì)象的屬性監(jiān)聽器
? ? ? ? target
.addOnPropertyChangedCallback(this);
? ?
}

? ?
...
}

private static class WeakListener<T> extends WeakReference<ViewDataBinding> {
? ?
private final ObservableReference<T> mObservable;
? ?
protected final int mLocalFieldId;
? ?
private T mTarget;

? ?
...

? ?
public void setTarget(T object) {
? ? ? ? unregister
();
? ? ? ? mTarget
= object;
? ? ? ?
if (mTarget != null) {
? ? ? ? ? ?
// mObservable 是上面的 WeakPropertyListener對(duì)象
? ? ? ? ? ?
// mTarget 是綁定到listener上得Observable對(duì)象
? ? ? ? ? ? mObservable
.addListener(mTarget);
? ? ? ?
}
? ?
}

? ?
...
}

CREATE_PROPERTY_LISTENER 實(shí)際上只是一個(gè)接口實(shí)例,注冊(cè)時(shí)會(huì)調(diào)用它的create()方法創(chuàng)建一個(gè)弱引用listener,它的作用是將listener綁定到Observable對(duì)象上,
綁定時(shí),會(huì)調(diào)用 listener.setTarget(…) 將Observable對(duì)象傳給 WeakPropertyListener實(shí)例,然后,WeakPropertyListener 會(huì)為 Observable對(duì)象添加OnPropertyChangedCallback。

  • addOnPropertyChangedCallback實(shí)現(xiàn)

addOnPropertyChangedCallback 在 BaseObservable中實(shí)現(xiàn),首先會(huì)實(shí)例化一個(gè)PropertyChangeRegistry對(duì)象,同時(shí)創(chuàng)建一個(gè)用來通知Observable對(duì)象重新綁定更新的回調(diào)CallbackRegistry.NotifierCallback。然后將 OnPropertyChangedCallback 添加到PropertyChangeRegistry的回調(diào)列表中

@Override
public synchronized void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
? ?
if (mCallbacks == null) {
? ? ? ? mCallbacks
= new PropertyChangeRegistry();
? ?
}
? ? mCallbacks
.add(callback);
}

這樣,注冊(cè)O(shè)bservable對(duì)象的監(jiān)聽就完畢了。

更新(重新綁定)Observable對(duì)象

設(shè)置或更新Observable對(duì)象時(shí)都會(huì)調(diào)用notifyPropertyChanged()或notifyChange()來通知更新,那到底是如何更新的呢?

  • 回調(diào)過程
public void notifyPropertyChanged(int fieldId) {
? ?
// mCallbacks 是 PropertyChangeRegistry對(duì)象,在 addOnPropertyChangedCallback 時(shí)實(shí)例化
? ?
// 如果注冊(cè)了Observable對(duì)象監(jiān)聽,那么mCallbacks不為null
? ?
if (mCallbacks != null) {
? ? ? ? mCallbacks
.notifyCallbacks(this, fieldId, null);
? ?
}
}

// baseLibrary
private void notifyCallbacks(T sender, int arg, A arg2, int startIndex, int endIndex, long bits) {
? ?
long bitMask = 1L;
? ?
for(int i = startIndex; i < endIndex; ++i) {
? ? ? ?
if((bits & bitMask) == 0L) {
? ? ? ? ? ?
// mNotifier 是實(shí)例化PropertyChangeRegistry時(shí)創(chuàng)建的
? ? ? ? ? ?
// mNotifier 即 CallbackRegistry.NotifierCallback
? ? ? ? ? ?
this.mNotifier.onNotifyCallback(this.mCallbacks.get(i), sender, arg, arg2);
? ? ? ?
}
? ? ? ? bitMask
<<= 1;
? ?
}
}

// PropertyChangeRegistry.NOTIFIER_CALLBACK
public void onNotifyCallback(Observable.OnPropertyChangedCallback callback, Observable sender,
? ? ? ?
int arg, Void notUsed) {
? ?
// callback 是為Observable對(duì)象添加的OnPropertyChangedCallback,即WeakPropertyListener
? ? callback
.onPropertyChanged(sender, arg);
}

// WeakPropertyListener
public void onPropertyChanged(Observable sender, int propertyId) {
? ?
// binder 即生成的Binding類對(duì)象
? ?
ViewDataBinding binder = mListener.getBinder();
? ?
...
? ? binder
.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
}

private void handleFieldChange(int mLocalFieldId, Object object, int fieldId) {
? ?
// onFieldChange 實(shí)現(xiàn)在生成的Binding類中
? ?
boolean result = onFieldChange(mLocalFieldId, object, fieldId);
? ?
if (result) {
? ? ? ?
// 如果對(duì)象屬性變化,將重新綁定
? ? ? ? requestRebind
();
? ?
}
}

通過 notifyPropertyChanged 調(diào)用到 mNotifier 回調(diào), mNotifier 通知OnPropertyChangedCallback Observable對(duì)象屬性發(fā)生變化,然后在onPropertyChanged中又轉(zhuǎn)給ViewDataBinding對(duì)象(生成的Binding類)處理。

  • 判斷是否需要重新綁定并執(zhí)行,在生成的Binding類中實(shí)現(xiàn)
// 生成的Binding類中得方法
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
? ?
// 如果變量不是Observable類型或沒有添加 Bindable注解,就不會(huì)判斷,直接返回false
? ?
switch (localFieldId) {
? ? ? ?
case 0 :
? ? ? ? ? ?
return onChangeContact((com.connorlin.databinding.model.ObservableContact) object, fieldId);
? ?
}
? ?
return false;
}

private boolean onChangeContact(com.connorlin.databinding.model.ObservableContact contact, int fieldId) {
? ?
switch (fieldId) {
? ? ? ?
case BR.name: {
? ? ? ? ? ?
synchronized(this) {
? ? ? ? ? ? ? ? ? ? mDirtyFlags
|= 0x4L;// 通過mDirtyFlags判斷對(duì)象是否變化
? ? ? ? ? ?
}
? ? ? ? ? ?
return true;
? ? ? ?
}
? ? ? ?
...
? ?
}
? ?
return false;
}

至此,更新過程完畢。

整個(gè)注冊(cè)與更新過程可以用一張流程圖來概括:

事件處理

事件處理的原理很簡(jiǎn)單,在生成Binding類中會(huì)實(shí)現(xiàn)View事件的監(jiān)聽,在構(gòu)造時(shí)實(shí)例化View的事件監(jiān)聽,然后在綁定時(shí)將事件監(jiān)聽對(duì)象賦值給對(duì)應(yīng)View,這樣,點(diǎn)擊時(shí)就會(huì)觸發(fā)相應(yīng)的監(jiān)聽。

這里以?DataBindingDemo?中 EventActivity部分為例:

  • 生成的Binding類并實(shí)現(xiàn)View的事件監(jiān)聽
public class ActivityEventBinding extends Android.databinding.ViewDataBinding
? ?
implements Android.databinding.generated.callback.OnCheckedChangeListener.Listener,
? ? ? ?
Android.databinding.generated.callback.OnClickListener.Listener {
? ?
// Checkbox check監(jiān)聽
? ?
private final Android.widget.CompoundButton.OnCheckedChangeListener mCallback3;
? ?
private final Android.view.View.OnClickListener mCallback2;
? ?
private final Android.view.View.OnClickListener mCallback1;
? ?
// listeners
? ?
private OnClickListenerImpl mAndroidViewViewOnCl;
? ?
...
? ?
// Listener Stub Implementations
? ?
public static class OnClickListenerImpl implements Android.view.View.OnClickListener{
? ? ? ?
private com.connorlin.databinding.handler.EventHandler value;
? ? ? ?
public OnClickListenerImpl setValue(com.connorlin.databinding.handler.EventHandler value) {
? ? ? ? ? ?
this.value = value;
? ? ? ? ? ?
return value == null ? null : this;
? ? ? ?
}
? ? ? ?
@Override
? ? ? ?
public void onClick(Android.view.View arg0) {
? ? ? ? ? ?
this.value.onClickFriend(arg0);
? ? ? ?
}
? ?
}
? ?
...
}
  • 實(shí)例化View的事件監(jiān)聽
public ActivityEventBinding(Android.databinding.DataBindingComponent bindingComponent, View root) {
? ?
super(bindingComponent, root, 0);
? ?
...
? ?
// listeners
? ? mCallback3
= new Android.databinding.generated.callback.OnCheckedChangeListener(this, 3);
? ? mCallback2
= new Android.databinding.generated.callback.OnClickListener(this, 2);
? ? mCallback1
= new Android.databinding.generated.callback.OnClickListener(this, 1);
? ? invalidateAll
();
}
  • 在執(zhí)行綁定中綁定View事件監(jiān)聽
@Override
protected void executeBindings() {
? ?
...
? ?
if ((dirtyFlags & 0x6L) != 0) {
? ? ? ?
if (handler != null) {
? ? ? ? ? ?
// read handler::onClickFriend
? ? ? ? ? ?
AndroidViewViewOnCli = (((mAndroidViewViewOnCl == null)
? ? ? ? ? ? ? ?
? (mAndroidViewViewOnCl = new OnClickListenerImpl()) : mAndroidViewViewOnCl).setValue(handler));
? ? ? ?
}
? ?
}
? ?
// batch finished
? ?
if ((dirtyFlags & 0x6L) != 0) {
? ? ? ?
this.mboundView1.setOnClickListener(AndroidViewViewOnCli);
? ?
}
? ?
if ((dirtyFlags & 0x4L) != 0) {
? ? ? ?
this.mboundView2.setOnClickListener(mCallback1);
? ? ? ?
this.mboundView3.setOnClickListener(mCallback2);
? ? ? ?
Android.databinding.adapters.CompoundButtonBindingAdapter.setListeners(
? ? ? ? ? ?
this.mboundView4, mCallback3, (Android.databinding.InverseBindingListener)null);
? ?
}
}
  • 觸發(fā)事件并執(zhí)行

ViewStub

原理類似,只是利用 ViewStubProxy 來延遲綁定。

  • 使用layout中的ViewStub實(shí)例化一個(gè)ViewStubProxy對(duì)象賦給viewstub變量,并與Bingding關(guān)聯(lián)
public ActivityViewStubBinding(Android.databinding.DataBindingComponent bindingComponent, View root) {
? ?
super(bindingComponent, root, 0);
? ?
final Object[] bindings = mapBindings(bindingComponent, root, 2, sIncludes, sViewsWithIds);
? ?
...
? ?
this.viewStub = new Android.databinding.ViewStubProxy((Android.view.ViewStub) bindings[1]);
? ?
this.viewStub.setContainingBinding(this);
? ?
...
}
  • 實(shí)例化ViewStubProxy的同時(shí)會(huì)注冊(cè)inflate監(jiān)聽
private OnInflateListener mProxyListener = new OnInflateListener() {
? ?
@Override
? ?
public void onInflate(ViewStub stub, View inflated) {
? ? ? ? mRoot
= inflated;
? ? ? ? mViewDataBinding
= DataBindingUtil.bind(mContainingBinding.mBindingComponent,
? ? ? ? ? ? ? ? inflated
, stub.getLayoutResource());
? ? ? ? mViewStub
= null;

? ? ? ?
if (mOnInflateListener != null) {
? ? ? ? ? ? mOnInflateListener
.onInflate(stub, inflated);
? ? ? ? ? ? mOnInflateListener
= null;
? ? ? ?
}
? ? ? ? mContainingBinding
.invalidateAll();
? ? ? ? mContainingBinding
.forceExecuteBindings();
? ?
}
};

public ViewStubProxy(ViewStub viewStub) {
? ? mViewStub
= viewStub;
? ? mViewStub
.setOnInflateListener(mProxyListener);
}
  • inflate ViewStub
if (!mActivityViewStubBinding.viewStub.isInflated()) {
? ? mActivityViewStubBinding
.viewStub.getViewStub().inflate();
}

當(dāng)ViewStub infate時(shí),執(zhí)行mProxyListener,其中會(huì)生成ViewStub的Binding,并強(qiáng)制執(zhí)行主Binding重綁

  • 綁定ViewStub
@Override
protected void executeBindings() {
? ?
long dirtyFlags = 0;
? ?
synchronized(this) {
? ? ? ? dirtyFlags
= mDirtyFlags;
? ? ? ? mDirtyFlags
= 0;
? ?
}
? ?
// batch finished
? ?
if (viewStub.getBinding() != null) {
? ? ? ? viewStub
.getBinding().executePendingBindings();
? ?
}
}

這樣,ViewStub綁定就結(jié)束了。

總結(jié)

以上是生活随笔為你收集整理的Android的DataBinding原理介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。