LiveData源码分析
LiveData使得 数据的更新 能以观察者模式 被observer感知,且此感知只发生在 LifecycleOwner的活跃生命周期状态。
具有以下优点:
1、确保界面符合数据状态,当生命周期状态变化时,LiveData通知Observer,可以在observer中更新界面。观察者可以在生命周期状态更改时刷新界面,而不是在每次数据变化时刷新界面。
2、不会发生内存泄漏,observer会在LifecycleOwner状态变为DESTROYED后自动remove。
3、不会因 Activity 停止而导致崩溃,如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件。
4、不需要手动解除观察,开发者不需要在onPause或onDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作。
5、数据始终保持最新状态,数据更新时 若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据。例如,曾经在后台的 Activity
会在返回前台后,observer立即接收最新的数据。
LiveData的使用
private MutableLiveData<String> infos;
public MutableLiveData<String> getInfo(){
if (infos == null){
infos = new MutableLiveData<>();
}
return infos;
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int x = myViewModel.increaseNumber();
myViewModel.getInfo().setValue("info = " + x);
}
});
myViewModel.getInfo().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
textView.setText(s);
}
});
这里是把livedata放在viewmodel里面。先在viewmodel定义一个livedata。然后在activity里面通过setValue(),设置数据,然后有数据改变,就会调用onChange()回调。还有一种设置数据的方法,postValue,它与setValue的区别是它在子线程操作,最后调用的还是setValue().源码在后面分析。
如果我们需要改变某个livedata的值,我们可以用map这个函数进行操作。
private MutableLiveData<Integer> liveData = new MutableLiveData<>();
public MutableLiveData<String> getLiveData(){
LiveData<String> stringLiveData = Transformations.map(liveData, input -> {
String s = input + " + Transformations.map";
Log.i("zzf", "apply: " + s);
return s;
});
return (MutableLiveData<String>) stringLiveData;
}
如果想要根据某个值 切换观察不同LiveData数据,则可以使用Transformations.switchMap()方法。
MutableLiveData<String> liveData3 = new MutableLiveData<>();
MutableLiveData<String> liveData4 = new MutableLiveData<>();
MutableLiveData<Boolean> liveDataSwitch = new MutableLiveData<>();
public LiveData<String> liveDataSwitch1 = Transformations.switchMap(liveDataSwitch, input -> {
if (input){
return liveData3;
}
return liveData4;
});
除了上面可以变换之外,还可以用MediatorLiveData来观察多个对象。
MediatorLiveData 是 LiveData 的子类,允许合并多个 LiveData 源。只要任何原始的 LiveData 源对象发生更改,就会触发 MediatorLiveData 对象的观察者。
//观察多个数据
MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<>();
MutableLiveData<String> liveData5 = new MutableLiveData<>();
MutableLiveData<String> liveData6 = new MutableLiveData<>();
mediatorLiveData.addSource(liveData5, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.i("zzf", "onChanged3: " + s);
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.addSource(liveData6, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.i("zzf", "onChanged4: " + s);
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.i("zzf", "onChanged5: "+s);
//无论liveData5、liveData6更新,都可以接收到
}
});
}
源码分析
首先我们需要调用setValue或者postValue数据更新:
setValue
protected void setValue(T value) {
assertMainThread("setValue");
//版本号
mVersion++;
mData = value;
//分发数据
dispatchingValue(null);
}
postValue
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
从上面可以看出postValue调用线程池,将数据包装成一个runnable。
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
实际是调用DefaultTaskExecutor的postToMainThread(),
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
最终创建一个主线程的handler。
从上面可知,两个方法最终走的还是setValue(),先判断是否在主线程,然后调用dispatchingValue()进行数据分发。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
////如果当前正在分发,则分发无效,return
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
//标记正在分发
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//observerWrapper不为空,使用considerNotify()通知真正的观察者
considerNotify(initiator);
initiator = null;
} else {
//observerWrapper为空,遍历通知所有的观察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
里面含有两个变量,mDispatchingValue表示是否正在分发,mDispatchInvalidated表示是否分发无效。
private void considerNotify(ObserverWrapper observer) {
//observer是否是活跃状态,不是则返回
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//observer的最后版本号如果大于mVersion,表明不是最新数据,则直接return,反之则将mVersion赋值给observer的最后版本号
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//回调onChanged()
observer.mObserver.onChanged((T) mData);
}
回调成功之后,则在下面进行UI设置。
myViewModel.getInfo().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
textView.setText(s);
}
});
下面我们来看observe,看它是怎么设置观察者的?
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
将传进来的owner和observer封装成一个LifecycleBoundObserver对象,为Lifecycle添加一个观察者。下面来看一下Lifecycle是什么东西。
public abstract class Lifecycle {
//添加观察者
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除观察者
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//获取当前状态
public abstract State getCurrentState();
//生命周期事件,对应Activity生命周期方法
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY //可以响应任意一个事件
}
//生命周期状态. (Event是进入这种状态的事件)
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
//判断至少是某一状态
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
1、Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:
2、Event,生命周期事件,这些事件对应Activity/Fragment生命周期方法。
State,生命周期状态,而Event是指进入一种状态的事件。
而Event与State的关系为:
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
也就是通过添加一个观察者,然后根据在不同的生命周期状态做对应的事情。
下面我们来看下LifecycleBoundObserver:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
//状态至少为STARTED状态
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//如果当前状态为DESTROYED则直接移除观察者,并返回
//如果当前状态与前面的状态不一致,进行状态切换
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
状态切换
void activeStateChanged(boolean newActive) {
//活跃状态 未发生变化时,不会处理。
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
//活跃则进行分发
if (mActive) {
dispatchingValue(this);
}
}
void changeActiveCounter(int change) {
int previousActiveCount = mActiveCount;
mActiveCount += change;
if (mChangingActiveState) {
return;
}
mChangingActiveState = true;
try {
while (previousActiveCount != mActiveCount) {
boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
previousActiveCount = mActiveCount;
if (needToCallActive) {
onActive();
} else if (needToCallInactive) {
onInactive();
}
}
} finally {
mChangingActiveState = false;
}
}
mActiveCount == 0 是指 LiveData 的活跃观察者数量。活跃的观察者数量 由0变为1、由1变为0 会分别调用LiveData的 onActive()、onInactive()方法。这就是前面提到的扩展使用的回调方法。