jetpack系列文章:Databinding源码分析(二):动态数据更新

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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值