美文网首页
Databinding原理解析(三)-model驱动view更新

Databinding原理解析(三)-model驱动view更新

作者: 烧伤的火柴 | 来源:发表于2020-04-30 17:29 被阅读0次

介绍

本篇介绍当model更新数据的时候,View如何自动更新的。
注意
源码对这一块的处理非常的复杂,梳理的时候非常烧脑。

我们接着ActivityMainBindingImpl.executeBindings()方法,这个方法中没有一个view都会调用updateRegistration更新注册表。

我们就从updateRegistration着手

注册回调

    protected boolean updateRegistration(int localFieldId, Observable observable) {
        return updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER);
    }

这个方法传进来的是一个Observable ,而我们的ObservableField是Observable的一个子类,这里一定要记住这一点,因为后边都是根据这个类处理逻辑的。

CREATE_PROPERTY_LISTENER这个对象里边很复杂,这个就像一个门面模式中的门面,所有的逻辑都在内部实现,这就是一个对外的门面,供外部使用。

    private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() {
        @Override
        public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
            return new WeakPropertyListener(viewDataBinding, localFieldId).getListener();
        }
    };

如果你正在看源码,看到这里请你向下看看,其他几个静态对象 CREATE_LIST_LISTENER,CREATE_MAP_LISTENER,等等这几个对应着其他的可观察对象ObservableList等等。
我们看看WeakPropertyListener的内容

 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);//1
        }

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

        @Override
        public void addListener(Observable target) {
            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?
            }
            binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
        }
    }

注意这个类继承Observable.OnPropertyChangedCallback并且实现了ObservableReference。
我们看看注释1的实现

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

        public WeakListener(ViewDataBinding binder, int localFieldId,
                ObservableReference<T> observable) {
            super(binder, sReferenceQueue);
            mLocalFieldId = localFieldId;
            mObservable = observable;
        }

        public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
            mObservable.setLifecycleOwner(lifecycleOwner);
        }

        public void setTarget(T object) {//setTarget
            unregister();
            mTarget = object;
            if (mTarget != null) {
                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;
        }
    }

通过new出来的对象,传递的是WeakPropertyListener实例。

现在我们回到updateRegistration方法中

    private boolean updateRegistration(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
     ...
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            registerTo(localFieldId, observable, listenerCreator);
            return true;
        }
       ....
    }

这时候的mLocalFieldObservers数组是没有内容的。我们看一下registerTo

    protected void registerTo(int localFieldId, Object observable,
            CreateWeakListener listenerCreator) {
       ....
        WeakListener listener = mLocalFieldObservers[localFieldId];
        if (listener == null) {
            listener = listenerCreator.create(this, localFieldId);
            mLocalFieldObservers[localFieldId] = listener;
            if (mLifecycleOwner != null) {
                listener.setLifecycleOwner(mLifecycleOwner);
            }
        }
        listener.setTarget(observable);
    }

这里通过刚才的CREATE_PROPERTY_LISTENER的create创建一个WeakListener实例,紧接着调用了setTarget将我们传递的BaseObservableField实例传递进去了。

我们回到WeakListener.setTarget的方法中

 public void setTarget(T object) {
            unregister();
            mTarget = object;
            if (mTarget != null) {
                mObservable.addListener(mTarget);
            }
        }

还记得前边说的mObservable是new WeakListener传递的WeakPropertyListener实例吗?

   @Override
        public void addListener(Observable target) {
            target.addOnPropertyChangedCallback(this);
        }

这里的target是我们的BaseObservableField实例name或者nickName

我们去看看BaseObservableField的addOnPropertyChangedCallback,实际是父类BaseObservable的实现

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

mCallbacks 是null所以new 一个PropertyChangeRegistry 对象

public class PropertyChangeRegistry extends
        CallbackRegistry<Observable.OnPropertyChangedCallback, Observable, Void> {

    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);
        }
    };

    public PropertyChangeRegistry() {
        super(NOTIFIER_CALLBACK);
    }
}

PropertyChangeRegistry 内部一个常量NOTIFIER_CALLBACK实现了NotifierCallback接口。空构造方法中调用了父类CallbackRegistry的构造。

  public CallbackRegistry(NotifierCallback<C, T, A> notifier) {
        mNotifier = notifier;
    }

分析到这里,我们发现了监听事件的notifier注册到了CallbackRegistry(回调注册器)中了。

通知更新

我们从userInfo.setNickName("延迟三秒");入手
调用到ObservableField的set方法

   public void set(T value) {
        if (value != mValue) {
            mValue = value;
            notifyChange();
        }
    }

BaseObservable.notifyChange方法

    public void notifyChange() {
        synchronized (this) {
            if (mCallbacks == null) {
                return;
            }
        }
        mCallbacks.notifyCallbacks(this, 0, null);
    }

前边已经把回调注册进来了,所以mCallbacks不在是null了。

public synchronized void notifyCallbacks(T sender, int arg, A arg2) {
        mNotificationLevel++;
        notifyRecurse(sender, arg, arg2);
        mNotificationLevel--;
     
         ...
    }

notifyChange是通知页面内所有的View都更新数据,所以这里是递归通知回调。

    private void notifyRecurse(T sender, int arg, A arg2) {
        final int callbackCount = mCallbacks.size();
        final int remainderIndex = mRemainderRemoved == null ? -1 : mRemainderRemoved.length - 1;
.
        notifyRemainder(sender, arg, arg2, remainderIndex);

        final int startCallbackIndex = (remainderIndex + 2) * Long.SIZE;

        notifyCallbacks(sender, arg, arg2, startCallbackIndex, callbackCount, 0);
    }
   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;
        }
    }

我们回到PropertyChangeRegistry#NOTIFIER_CALLBACK中

        @Override
        public void onNotifyCallback(Observable.OnPropertyChangedCallback callback, Observable sender,
                int arg, Void notUsed) {
            callback.onPropertyChanged(sender, arg);
        }

callback调用onPropertyChanged方法,这个callback是WeakPropertyListener实例。

  @Override
        public void onPropertyChanged(Observable sender, int propertyId) {
            ViewDataBinding binder = mListener.getBinder();
            ...
            binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId);
        }
    private void handleFieldChange(int mLocalFieldId, Object object, int fieldId) {
       ...
        boolean result = onFieldChange(mLocalFieldId, object, fieldId);
        if (result) {
            requestRebind();
        }
    }

onFieldChange的实现在ActivityMainBindingImpl中

   @Override
    protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
        switch (localFieldId) {
            case 0 :
                return onChangeUserInfoNickName((androidx.databinding.ObservableField<java.lang.String>) object, fieldId);
            case 1 :
                return onChangeUserInfoName((androidx.databinding.ObservableField<java.lang.String>) object, fieldId);
        }
        return false;
    }

我前边调用的是setNickName 函数,所以localFieldId是0.

private boolean onChangeUserInfoNickName(androidx.databinding.ObservableField<java.lang.String> UserInfoNickName, int fieldId) {
        if (fieldId == BR._all) {
            synchronized(this) {
                    mDirtyFlags |= 0x1L;
            }
            return true;
        }
        return false;
    }

notifyChange()传递的是0 即fieldId ==BR._all 是true。

回到handleFieldChange函数中,继续执行requestRebind,后边的流程我们在上一篇文章分析过了。

总结

model驱动view更新的过程,注册观察者回调是一个很烧脑的过程,需要慢慢分析。

相关文章

  • Databinding原理解析(三)-model驱动view更新

    介绍 本篇介绍当model更新数据的时候,View如何自动更新的。注意源码对这一块的处理非常的复杂,梳理的时候非常...

  • js实现双向数据绑定

    单向数据绑定  把Model绑定到view,Model更新,View将会自动更新双向数据绑定  用户更新view,...

  • Databinding原理解析(四)-双向绑定的View驱动Mo

    介绍 本篇介绍双向绑定中的View驱动Model更新数据。 添加监听器 我们在ActivityMainBindin...

  • vue3响应式数据原理

    Effect 原理解析 与 实现 引言: vue、react 框架的核心都是数据驱动视图也就是model => v...

  • 面试复习(二) Java篇

    三大框架MVC(Model、View、Controller)参考image原理:view层发送指令到control...

  • dataBinding原理

    dataBinding如何绑定View? dataBinding如何修改View?

  • vue

    MVVM model和view层通过中间的vm连接和驱动。model层数据变化会改变视图,view改变通过事件来修...

  • MVC&MVVC

    MVC 单项数据流 View上用户行为导致Model更新 用户的行为,有些会导致model的更新,View会通过T...

  • MVVM、MVC

    什么是MVVM MVVM是Model-View-ViewModel的缩写,核心为VM,数据驱动视图Model可以理...

  • DataBinding深入使用(二)

    本文主要介绍Databinding 中View与Model的双向绑定 1.实现双向绑定主要依赖与 data类的实现...

网友评论

      本文标题:Databinding原理解析(三)-model驱动view更新

      本文链接:https://www.haomeiwen.com/subject/hbwzwhtx.html