
在liveData数据变化回调onChanged之后,触发requestRebind,在executeBindings时根据dirtyFlags通过BindingAdapter方法刷新View属性
基于androidx.databinding:databinding-runtime:4.0.1
private static DataBinderMapper sMapper = new DataBinderMapperImpl();
private static DataBindingComponent sDefaultComponent = null;
public static <T extends ViewDataBinding> T setContentView(@NonNull Activity activity,
int layoutId) {
return setContentView(activity, layoutId, sDefaultComponent);
}
public static <T extends ViewDataBinding> T setContentView(@NonNull Activity activity,
int layoutId, @Nullable DataBindingComponent bindingComponent) {
activity.setContentView(layoutId);
View decorView = activity.getWindow().getDecorView();
ViewGroup contentView = (ViewGroup) decorView.findViewById(android.R.id.content);
return bindToAddedViews(bindingComponent, contentView, 0, layoutId);
}
private static <T extends ViewDataBinding> T bindToAddedViews(DataBindingComponent component,
ViewGroup parent, int startChildren, int layoutId) {
final int endChildren = parent.getChildCount();
final int childrenAdded = endChildren - startChildren;
if (childrenAdded == 1) {
final View childView = parent.getChildAt(endChildren - 1);
return bind(component, childView, layoutId);
} else {
final View[] children = new View[childrenAdded];
for (int i = 0; i < childrenAdded; i++) {
children[i] = parent.getChildAt(i + startChildren);
}
return bind(component, children, layoutId);
}
}
static <T extends ViewDataBinding> T bind(DataBindingComponent bindingComponent, View[] roots,
int layoutId) {
return (T) sMapper.getDataBinder(bindingComponent, roots, layoutId);
}
public class MergedDataBinderMapper extends DataBinderMapper {
private List<DataBinderMapper> mMappers = new CopyOnWriteArrayList<>();
}
@Override
public ViewDataBinding getDataBinder(DataBindingComponent bindingComponent, View view,
int layoutId) {
for(DataBinderMapper mapper : mMappers) {
ViewDataBinding result = mapper.getDataBinder(bindingComponent, view, layoutId);
if (result != null) {
return result;
}
}
return null;
}
public class DataBinderMapperImpl extends MergedDataBinderMapper {
DataBinderMapperImpl() {
addMapper(new com.example.myapplication.DataBinderMapperImpl());
}
}
@Override
public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
final Object tag = view.getTag();
switch(localizedLayoutId) {
case LAYOUT_ACTIVITYLOGIN: {
if ("layout/activity_login_0".equals(tag)) {
return new ActivityLoginBindingImpl(component, view);
}
}
}
}
private final Choreographer.FrameCallback mFrameCallback;
private static final CreateWeakListener CREATE_LIVE_DATA_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
return new LiveDataListener(viewDataBinding, localFieldId).getListener();
}
};
protected ViewDataBinding(DataBindingComponent bindingComponent, View root, int localFieldCount) {
mBindingComponent = bindingComponent;
mLocalFieldObservers = new WeakListener[localFieldCount];
this.mRoot = root;
mChoreographer = Choreographer.getInstance();
mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
mRebindRunnable.run();
}
};
}
public void setLifecycleOwner(@Nullable LifecycleOwner lifecycleOwner) {
......
mLifecycleOwner = lifecycleOwner;
if (lifecycleOwner != null) {
if (mOnStartListener == null) {
mOnStartListener = new OnStartListener(this);
}
lifecycleOwner.getLifecycle().addObserver(mOnStartListener);
}
for (WeakListener<?> weakListener : mLocalFieldObservers) {
if (weakListener != null) {
weakListener.setLifecycleOwner(lifecycleOwner);
}
}
}
static class OnStartListener implements LifecycleObserver {
final WeakReference<ViewDataBinding> mBinding;
private OnStartListener(ViewDataBinding binding) {
mBinding = new WeakReference<>(binding);
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
ViewDataBinding dataBinding = mBinding.get();
if (dataBinding != null) {
dataBinding.executePendingBindings();
}
}
}
protected void requestRebind() {
if (mContainingBinding != null) {
mContainingBinding.requestRebind();
} else {
final LifecycleOwner owner = this.mLifecycleOwner;
if (owner != null) {
Lifecycle.State state = owner.getLifecycle().getCurrentState();
if (!state.isAtLeast(Lifecycle.State.STARTED)) {
return; // wait until lifecycle owner is started
}
}
mChoreographer.postFrameCallback(mFrameCallback);
}
}
private final Runnable mRebindRunnable = new Runnable() {
@Override
public void run() {
processReferenceQueue();
executePendingBindings();
}
};
public void executePendingBindings() {
if (mContainingBinding == null) {
executeBindingsInternal();
} else {
mContainingBinding.executePendingBindings();
}
}
private void executeBindingsInternal() {
.......
executeBindings();
......
}
protected boolean updateLiveDataRegistration(int localFieldId, LiveData<?> observable) {
mInLiveDataRegisterObserver = true;
try {
return updateRegistration(localFieldId, observable, CREATE_LIVE_DATA_LISTENER);
} finally {
mInLiveDataRegisterObserver = false;
}
}
private boolean updateRegistration(int localFieldId, Object observable,
CreateWeakListener listenerCreator) {
......
if (listener.getTarget() == observable) {
return false;//nothing to do, same object
}
unregisterFrom(localFieldId);
registerTo(localFieldId, observable, listenerCreator);
return true;
}
protected void registerTo(int localFieldId, Object observable,
CreateWeakListener listenerCreator) {
if (observable == null) {
return;
}
WeakListener listener = mLocalFieldObservers[localFieldId];
if (listener == null) {
listener = listenerCreator.create(this, localFieldId);
mLocalFieldObservers[localFieldId] = listener;
if (mLifecycleOwner != null) {
listener.setLifecycleOwner(mLifecycleOwner);
}
}
listener.setTarget(observable);
}
private void handleFieldChange(int mLocalFieldId, Object object, int fieldId) {
boolean result = onFieldChange(mLocalFieldId, object, fieldId);
if (result) {
requestRebind();
}
}
private static class LiveDataListener implements Observer, ObservableReference<LiveData<?>> {
final WeakListener<LiveData<?>> mListener;
LifecycleOwner mLifecycleOwner;
public LiveDataListener(ViewDataBinding binder, int localFieldId) {
mListener = new WeakListener(binder, localFieldId, this);
}
}
@Override
public WeakListener<LiveData<?>> getListener() {
return mListener;
}
@Override
public void addListener(LiveData<?> target) {
if (mLifecycleOwner != null) {
target.observe(mLifecycleOwner, this);
}
}
@Override
public void onChanged(@Nullable Object o) {
ViewDataBinding binder = mListener.getBinder();
if (binder != null) {
binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
}
}
private final ObservableReference<T> mObservable;
public void setTarget(T object) {
unregister();
mTarget = object;
if (mTarget != null) {
mObservable.addListener(mTarget);
}
}
private ActivityLoginBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root, 3
, (android.widget.Button) bindings[3]
, (android.widget.EditText) bindings[2]
, (com.example.myapplication.arch.login.CustomTextView) bindings[4]
, (android.widget.EditText) bindings[1]
);
this.login.setTag(null);
this.mboundView0 = (androidx.constraintlayout.widget.ConstraintLayout) bindings[0];
this.mboundView0.setTag(null);
this.password.setTag(null);
this.uid.setTag(null);
this.userName.setTag(null);
setRootTag(root);
// listeners
mCallback1 = new com.example.myapplication.generated.callback.OnClickListener(this, 1);
invalidateAll();
}
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x10L;
}
requestRebind();
}
public void setVm(@Nullable com.example.myapplication.arch.login.LoginViewModel Vm) {
this.mVm = Vm;
synchronized(this) {
mDirtyFlags |= 0x8L;
}
notifyPropertyChanged(BR.vm);
super.requestRebind();
}
@Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
case 0 :
return onChangeVmUserNameLiveData((androidx.lifecycle.MutableLiveData<java.lang.String>) object, fieldId);
case 1 :
return onChangeVmUidLiveData((androidx.lifecycle.MutableLiveData<java.lang.String>) object, fieldId);
case 2 :
return onChangeVmPasswordLiveData((androidx.lifecycle.MutableLiveData<java.lang.String>) object, fieldId);
}
return false;
}
private boolean onChangeVmUidLiveData(androidx.lifecycle.MutableLiveData<java.lang.String> VmUidLiveData, int fieldId) {
if (fieldId == BR._all) {
synchronized(this) {
mDirtyFlags |= 0x2L;
}
return true;
}
return false;
}
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
java.lang.String vmUserNameLiveDataGetValue = null;
androidx.lifecycle.MutableLiveData<java.lang.String> vmUserNameLiveData = null;
androidx.lifecycle.MutableLiveData<java.lang.String> vmUidLiveData = null;
com.example.myapplication.arch.login.LoginViewModel vm = mVm;
java.lang.String vmUidLiveDataGetValue = null;
java.lang.String vmPasswordLiveDataGetValue = null;
androidx.lifecycle.MutableLiveData<java.lang.String> vmPasswordLiveData = null;
......
if ((dirtyFlags & 0x1aL) != 0) {
if (vm != null) {
// read vm.uidLiveData
vmUidLiveData = vm.getUidLiveData();
}
updateLiveDataRegistration(1, vmUidLiveData);
if (vmUidLiveData != null) {
// read vm.uidLiveData.getValue()
vmUidLiveDataGetValue = vmUidLiveData.getValue();
}
//从LiveData的T中提取嵌套子数据data时,会生成如下的提取field代码
//xml中绑定的数据为: @{vm.uidLiveData.data}
if (vmUidLiveDataGetValue != null) {
// read vm.uidLiveData.getValue().data
vmUidLiveDataData = vmUidLiveDataGetValue.getData();
}
}
if ((dirtyFlags & 0x1aL) != 0) {
// api target 1
//从LiveData的T中提取嵌套子数据data时, 会用vmUidLiveDataData替代vmUidLiveDataGetValue
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.uid, vmUidLiveDataGetValue);
com.example.myapplication.arch.login.CustomTextView.changeBgIfLong(this.uid, vmUidLiveDataGetValue);
}
}
https://developer.android.google.cn/guide/topics/ui/layout/recyclerview