Databinding:单双向数据绑定
Databinding:动态数据更新
Lifecycle讲解
livedata源码分析
ViewModel源码+最终组合使用
前言
通过上一节的分析,了解了单双向数据的绑定,其实Databinding框架是一个观察者模式,你要说订阅分发也行,先复习一下观察者模式:简单来说就是被观察者中为了一个集合,将观察者注册到这个集合当中,当有数据变化时,遍历分发消息,通知观察者。
道理呢就是这么个道理,先来看一段入口代码:
//上一节其实就分析了这一句,实现了单双向数据绑定
ActivityDbBinding dbBinding = DataBindingUtil.setContentView(this, R.layout.activity_db);
User user = new User("Jiang", "tao", "111");
//这一节类分析第二句,实现观察者模式的注册监听
dbBinding.setUser(user);
这个方法主要就两句话
public void setUser(@Nullable com.example.myapplication.bean.User User) {
updateRegistration(0, User); (1)设置注册观察者和被观察者
this.mUser = User;
synchronized(this) {
mDirtyFlags |= 0x1L;
}
notifyPropertyChanged(BR.user);(2)分发通知观察者,更新数据
super.requestRebind(); (3)这个上节讲过,调用它能刷新UI控件中的数据
}
步骤一、注册观察者
这里跳转的有点绕,我们随时记录关键点:
首先是调用父类中同名updateRegistration方法,localFieldId是0,observable是User对象,这里新增了一个CREATE_PROPERTY_LISTENER东西:
protected boolean updateRegistration(int localFieldId, Observable observable) {
return updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
}
CREATE_PROPERTY_LISTENER这个东西其实是一个WeakListener监听器,里面用来创建并得到WeakPropertyListener对象,是个静态内部类,从名字就可以看出是个弱引用,里面有引用了观察者对象,也是为了防止界面销毁时可能导致的内存溢出。
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
}
};
继续执行updateRegistration方法:这里是从本地监听数组中获取对应的监听器,刚进来肯定没有,所以通过registerTo注册一个
private boolean updateRegistration(int localFieldId, Object observable,
CreateWeakListener listenerCreator) {
...........
WeakListener listener = mLocalFieldObservers[localFieldId];
if (listener == null) {
registerTo(localFieldId, observable, listenerCreator);
return true;
}
.......
}
这个是核心方法,通过两步骤完成观察者模式的注册工作。
其中this是当前的viewDataBinding,就是当前view
protected void registerTo(int localFieldId, Object observable,
CreateWeakListener listenerCreator) {
.......日常判空........
WeakListener listener = mLocalFieldObservers[localFieldId];
if (listener == null) {
listener = listenerCreator.create(this, localFieldId);(1)创建一个弱引用的观察者对象
mLocalFieldObservers[localFieldId] = listener;
if (mLifecycleOwner != null) {
listener.setLifecycleOwner(mLifecycleOwner);
}
}
listener.setTarget(observable);(2)将观察者注册到被观察者中去
}
(1)在create中创建了WeakListener;binder就是当前view就是观察者,注意这里将this也扔了进去。
public WeakPropertyListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener<Observable>(binder, localFieldId, this);
}
(2)setTarget是WeakListener类中的方法,调用了mObservable.addListener(mTarget),这个mObservable就是(1)中传入的this,也就是WeakPropertyListener对象。mTarget也就是User对象。
public void setTarget(T object) {
unregister();
mTarget = object;
if (mTarget != null) {
mObservable.addListener(mTarget);
}
}
这里又回到WeakPropertyListener中,调用addListener方法,target是User对象也就是观察者。this就是当前WeakPropertyListener对象,就是已经包装了view的被观察者。
public void addListener(Observable target) {
target.addOnPropertyChangedCallback(this);
}
因为User都继承了BaseObservable,最后将被观察者注册到mCallbacks集合中,结束
synchronized (this) {
if (mCallbacks == null) {
mCallbacks = new PropertyChangeRegistry();
}
}
mCallbacks.add(callback);
步骤二、分发通知观察者
当更新M层的数据时,都会调用notifyPropertyChanged()方法通知观察者。这里this时当前bean类,fieldld用来找出对应观察者,
notifyPropertyChanged(BR.user);
public void notifyPropertyChanged(int fieldId) {
synchronized (this) {
if (mCallbacks == null) {
return;
}
}
mCallbacks.notifyCallbacks(this, fieldId, null);
}
经过层层调用,最终调用了notifyCallbacks方法,其中就是遍历已经注册的观察者,然后调用mNotifier.onNotifyCallback方法进行分发通知
private void notifyCallbacks(T sender, int arg, A arg2, final int startIndex,
final int endIndex, final long bits) {
long bitMask = 1;
for (int i = startIndex; i < endIndex; i++) {
if ((bits & bitMask) == 0) {
mNotifier.onNotifyCallback(mCallbacks.get(i), sender, arg, arg2);
}
bitMask <<= 1;
}
}
mNotifier就是步骤一中在最后创建出来的PropertyChangeRegistry对象中NOTIFIER_CALLBACK,调用它的onNotifyCallback方法,其实就是调用观察者callback的onPropertyChanged方法。
private static final CallbackRegistry.NotifierCallback<Observable.OnPropertyChangedCallback, Observable, Void> NOTIFIER_CALLBACK = new CallbackRegistry.NotifierCallback<Observable.OnPropertyChangedCallback, Observable, Void>() {
@Override
public void onNotifyCallback(Observable.OnPropertyChangedCallback callback, Observable sender,
int arg, Void notUsed) {
callback.onPropertyChanged(sender, arg);
}
};
上面的这个callback就是步骤一中创建出来的WeakPropertyListener对象,调用其中的onPropertyChanged传入被观察者的数据。
//这个sender就是数据bean类
public void onPropertyChanged(Observable sender, int propertyId) {
ViewDataBinding binder = mListener.getBinder(); //这个binder就是view对象
if (binder == null) {
return;
}
//这个getTarget就是view对象私藏的bean对象。看看是不是一样,不一样就说明走错门了
Observable obj = mListener.getTarget();
if (obj != sender) {
return;
}
binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
}
看到没!看到没!看到没!requestRebind()方法。我草!就是它!
onFieldChange方法就是更新一下标志位,这也是databinding的一个数据刷新思想,改数据前先改标志位。
private void handleFieldChange(int mLocalFieldId, Object object, int fieldId) {
if (mInLiveDataRegisterObserver) {
return;
}
boolean result = onFieldChange(mLocalFieldId, object, fieldId);
if (result) {
requestRebind();
}
}