您当前的位置: 首页 >  xiangzhihong8 android

Android的DataBinding原理介绍

xiangzhihong8 发布时间:2016-09-28 11:20:59 ,浏览量:6

Activity在inflate layout时,通过DataBindingUtil来生成绑定,从代码看,是遍历contentView得到View数组对象,然后通过数据绑定library生成对应的Binding类,含Views、变量、listeners等。生成类位于
build/intermediates/classes/debug/…package…/databinding/xxx.Java 下,具体如何生成这里暂不作深入。

绑定过程

  • 首先,会在父类(ViewDataBinding)中实例化回调或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());
}
  • 接着,通过调用 mapBindings(…) 遍历布局以获得包含bound、includes、ID Views的数组对象,再依次赋给对应View
final Object[] bindings = mapBindings(bindingComponent, root, 3, sIncludes, sViewsWithIds);
this.mboundView0 = (Android.widget.LinearLayout) bindings[0];
this.mboundView0.setTag(null);
  • 然后,调用 invalidateAll() -> requestRebind() -> … -> mRebindRunnable.run() – 执行 Runnable
// 用于动态重新绑定 Views
private final Runnable mRebindRunnable = new Runnable() {
    @Override
    public void run() {
        synchronized (this) {
            mPendingRebind = false;
        }
        .....
        executePendingBindings();
    }
};
  • 最后,通过该Runnable会执行到 executePendingBindings() -> … -> executeBindings(),在这里会执行绑定相关操作。
@Override
protected void executeBindings() {
    long dirtyFlags = 0;
    synchronized(this) {
        dirtyFlags = mDirtyFlags;   // mDirtyFlags 变量更新的标志
        mDirtyFlags = 0;
    }
    .....
}

设置变量(数据对象)

普通 Java bean 对象

  • 首先,通过mDirtyFlags标识变量(所有变量共用)
synchronized(this) {
    mDirtyFlags |= 0x1L;
}
  • 然后,调用 notifyPropertyChanged(…) 来通知更新(若有回调)
public void notifyPropertyChanged(int fieldId) {
    if (mCallbacks != null) {
        mCallbacks.notifyCallbacks(this, fieldId, null);
    }
}
  • 最后,调用 requestRebind() -> … -> executeBindings() 再次执行绑定操作,将数据更新到Views上
@Override
protected void executeBindings() {
    long dirtyFlags = 0;
    synchronized(this) {
        dirtyFlags = mDirtyFlags;
        mDirtyFlags = 0;
    }
    .....
}

Observable 对象

  • 在设置变量时,会先调用 updateRegistration(..) 注册一个Observable对象的监听
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 对象

ObservableFields 对象

  • 前期步骤同普通 Java Bean 对象
  • 与 Observable 对象不同的是,Observable对象的监听是在 executeBindings() 中注册的
@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();
            }
        }
        ...
    }
    ...
}

注册Observable对象监听

  • 入口 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) {
    ...
    // 确保不重复监听,先移除再添加观察监听
    unregisterFrom(localFieldId);
    registerTo(localFieldId, observable, listenerCreator);
    return true;
}

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

    // 创建对象监听并存到mLocalFieldObservers中
    WeakListener listener = mLocalFieldObservers[localFieldId];
    if (listener == null) {
        // CREATE_PROPERTY_LISTENER -> create(...)
        listener = listenerCreator.create(this, localFieldId);
        mLocalFieldObservers[localFieldId] = listener;
    }

    // 将监听绑定到Observable对象上
    listener.setTarget(observable);
}

每个Observable对象都会添加一个观察监听,保存在数组 mLocalFieldObservers 中,并以 localFieldId 索引。

  • CREATE_PROPERTY_LISTENER 为何物?
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
    @Override
    public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
        // 返回从WeakPropertyListener实例中获取的监听器(WeakListener)
        return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
    }
}

private static class WeakPropertyListener extends Observable.OnPropertyChangedCallback
        implements ObservableReference {
    final WeakListener mListener;

    public WeakPropertyListener(ViewDataBinding binder, int localFieldId) {
        mListener = new WeakListener(binder, localFieldId, this);
    }

    @Override
    public WeakListener getListener() {
        return mListener;
    }

    @Override
    public void addListener(Observable target) {
        // WeakPropertyListener 继承于 Observable.OnPropertyChangedCallback,
        // 所以 this 其实就是 Observable对象的属性监听器
        target.addOnPropertyChangedCallback(this);
    }

    ...
}

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

    ...

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

    ...
}

CREATE_PROPERTY_LISTENER 实际上只是一个接口实例,注册时会调用它的create()方法创建一个弱引用listener,它的作用是将listener绑定到Observable对象上,
绑定时,会调用 listener.setTarget(…) 将Observable对象传给 WeakPropertyListener实例,然后,WeakPropertyListener 会为 Observable对象添加OnPropertyChangedCallback。

  • addOnPropertyChangedCallback实现

addOnPropertyChangedCallback 在 BaseObservable中实现,首先会实例化一个PropertyChangeRegistry对象,同时创建一个用来通知Observable对象重新绑定更新的回调CallbackRegistry.NotifierCallback。然后将 OnPropertyChangedCallback 添加到PropertyChangeRegistry的回调列表中

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

这样,注册Observable对象的监听就完毕了。

更新(重新绑定)Observable对象

设置或更新Observable对象时都会调用notifyPropertyChanged()或notifyChange()来通知更新,那到底是如何更新的呢?

  • 回调过程
public void notifyPropertyChanged(int fieldId) {
    // mCallbacks 是 PropertyChangeRegistry对象,在 addOnPropertyChangedCallback 时实例化
    // 如果注册了Observable对象监听,那么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
关注
打赏
查看更多评论

xiangzhihong8

暂无认证

  • 6浏览

    0关注

    1319博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录