Android - Jetpack LiveData源码探秘

90 阅读5分钟
LiveData 的两重身份(观察者与被观察者)
  • 作为观察者,它观察Activity、Fragment的生命周期,只有在active状态下才可能会分发Value;
  • 作为被观察者,当它的Value发生变化,对所有观察者分发Value;
注册LiveData监听者源码分析
//Activity类中使用
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    vm.data.observe(this, new Observer<String>() {//进入下面的LiveData.observe
        @Override
        public void onChanged(String s) {
        }
    });
}


//LiveData类中
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {//Activity状态为DESTROYED,则不注册,直接返回
        return;
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//1
    ......
    owner.getLifecycle().addObserver(wrapper);//2
}
  • 注释1:将Activity与LiveData观察者observer封装成LifecycleBoundObserver对象;
  • 注释2:在这里我们知道,观察Activity生命周期变化的不是LiveData而是LifecycleBoundObserver,当生命周期发生变化会通知LiveData分发Value;
LiveData 同步Value

注册时 的同步Value,关键在于上面的owner.getLifecycle().addObserver(wrapper),**owner.getLifecycle()返回LifecycleRegistry对象 **,其负责维护监听者以及对监听者进行生命周期状态同步;

//LifecycleRegistry类中
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//监听者初始状态为INITIALIZED,后续会用到,需要注意
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);//封装监听者以及状态
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);//放入map集合
    ......
    sync();//触发生命周期状态同步
     ......
}

//LifecycleRegistry类中
private void sync() {
     ......
    while (!isSynced()) {
        mNewEventOccurred = false;
        ......
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {//1
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}


private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        ......
        observer.dispatchEvent(lifecycleOwner, event);//2
        ......
    }
}


//ObserverWithState类中
void dispatchEvent(LifecycleOwner owner, Event event) {
    State newState = event.getTargetState();
    mState = min(mState, newState);
    mLifecycleObserver.onStateChanged(owner, event);//3
    mState = newState;
}

  • 注释1:mState代表LifecycleRegistry的状态,也就是Activity的状态,因为我们是在onCreate函数对LiveData注册监听的,所以mState为CREATED,newest.getValue().mState表示监听者状态,因为监听者还没有同步过状态,默认为INITIALIZED所以执行forwardPass()
  • 注释2: 分发事件Event,从INITIALIZED到CREATED,所以对应的event是ON_CREATE;
  • 注释3:mLifecycleObserver为生命周期的监听者LifecycleBoundObserver类型,触发其onStateChanged函数
//LifecycleBoundObserver类中
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
    if (currentState == DESTROYED) {//如果是DESTROYED状态,则移除监听
        removeObserver(mObserver);
        return;
    }
    Lifecycle.State prevState = null;
    while (prevState != currentState) {//1
        prevState = currentState;
        activeStateChanged(shouldBeActive());//2
        currentState = mOwner.getLifecycle().getCurrentState();
    }
}

//LifecycleBoundObserver类中
boolean shouldBeActive() {//3
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
  • 注释1:判断状态是否一致,用while循环,是因为有可能出现跨状态的情况,例如当前Activtiy是RESUMED状态,但监听器是INITIALIZED状态;
  • 注释2:触发其父类ObserverWrapper.activeStateChanged函数
  • 注释3:判断Activity是否存于活跃状态;
//ObserverWrapper类中
void activeStateChanged(boolean newActive) {
    ......
    if (mActive) {//1
        dispatchingValue(this);//ObserverWrapper是LiveData的内部类,所以调用下面的函数
    }
}

//LiveData类中
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);//调用下面的considerNotify函数
            initiator = null;
        } else {
            ......
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

//LiveData类中
private void considerNotify(ObserverWrapper observer) {
    ......
   
    if (observer.mLastVersion >= mVersion) {//2
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);//3
}

  • 注释1: 这里就是我们常说的,存于活跃状态时 LiveData才会分发Value;
  • 注释2: 判断版本,mVersion表示LiveData的版本,默认是-1,当数据发生变化则+1,observer.mLastVersion表示监听器的版本;当对LiveData数据发生修改,那么后注册的监听者在Activity活跃的时候,也能接收到数据,这就是常说的粘性数据,当然,如果注册之前LiveData数据没有修改过,那么就直接return。

数据变化时 的同步Value,当LiveData发生setValue或postValue

//LiveData类中
protected void setValue(T value) {
    mVersion++;//LiveData版本号+1
    mData = value;
    dispatchingValue(null);//调用下面的函数分发Value
}

//LiveData类中
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            ......
        } else {
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator 
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());//1
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}
  • 代码是否似曾相识,没错,跟注册时的同步Value一样,都走到dispatchingValue函数,只不过这次走的是else分支,遍历所有监听器进行分发。
LiveData 的不可变性

下面代码,为了控制MutableLiveData的修改权限收敛在vm内部,只保留不可以修改的LiveData,防止修改发散出现不可预知的情况。

class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data//只保留只有访问权限的LiveData
}
LiveData 去掉粘性

注册LiveData监听时,通过反射将监听者与LiveData的版本对齐,就可以避免收到粘性数据,网上有很多例子,这里就不展开了;

LiveData postValue 可能会数据丢失
protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;//1
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2
}


private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;//3
            mPendingData = NOT_SET;
        }
        setValue((T) newValue);
    }
};
  • 注释1:子线程执行postValue,mPendingData默认值为NOT_SET,所以postTask为true;
  • 注释2:ArchTaskExecutor.getInstance().postToMainThread 往主线程post setValue任务;
  • 注释3:任务核心,将新值newValue通过setValue分发出去,把mPendingData重置;
  • 因为postTask 变量的存在,执行postValue函数(生产者)在Runnable任务(消费者)没有处理完之前是会直接true的,当执行生产者速度比消费者快,可能会出现数据丢失,。例如,子线程连续执行postValue(1)、postValue(2),当postValue(1)对应的Runnable没有执行完,此时mPendingData值为1,接着立马触发postValue(2),因为mPendingData值为1,导致postTask为false,所以postValue函数就直接true了,postValue(2)这条数据就丢失了。
LiveData的思考
  • 适用场景:数据驱动的场景,也叫事件驱动,例如当List集合数据发生变化,同步给多个监听者;
  • 不适用场景:生产者速度比消费速度快的场景,例如文件下载进度更新;
  • 不适用场景:状态同步场景,例如Activity通过vm的LiveData驱动Fragment toast消息,那么当Fragment关闭再次弹起,也会收到这个粘性回调。
涉及类
  • MutableLiveData类继承LiveData,遵循最小知识原则,只提供setValue\postValue等几个接口;
  • LiveData类维护版本、监听者集合、负责Value的分发;
  • ObserverWrapper类,负责通知LiveData监听者数据有变化;
  • LifecycleBoundObserver类继承ObserverWrapper,封装Activity、Fragment+LiveData监听者,它才是监听生命周期变化的核心,当生命周期发生变化 通知LiveData监听者数据有变化;
  • AlwaysActiveObserver类继承ObserverWrapper,对比LifecycleBoundObserver,它不做生命周期监听,只要数据有变化,则通知LiveData监听者数据有变;
  • LifecycleRegistry,负责维护生命周期监听者以及做生命周期同步;
总结
  • LiveData适合用在数据驱动的场景,因为其粘性问题,所以不适合状态驱动的场景;
  • 暴露不可修改的LiveData,对其修改权限进行控制。

以上分析有不对的地方,请指出,互相学习,谢谢哦!