前言
LiveData是一个可观察的数据持有者类,与常规observable不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如Activity,Fragment或Service。此感知确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者,它遵循观察者模式,而且不存在内存泄漏问题,观察组件不在活跃状态,不会收到消息,更新UI。
本文侧重原理探究
目录
一、LiveData简单示例
LiveData的使用大家都会,对其优缺点可以参考 Jetpack之LiveData
1、跨组件更新数据
主要是简单的跳转,第二个页面显示数据
public class DataShareActivity extends AppCompatActivity {
private TextView mTvShare1;
private Button mBtnShare1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_share);
findViews();
mTvShare1.setText("First Page Initialed");
mBtnShare1.setOnClickListener(v -> {
ShareLiveData.getInstance().setValue(new ShareModel("First Page Jump To Me"));
startActivity(new Intent(DataShareActivity.this,DataShareTwoActivity.class));
});
LiveData<ShareModel> shareModelLiveData = ShareLiveData.getInstance();
shareModelLiveData.observe(this,(value)->{
if(value == null){
return;
}
mTvShare1.setText(value.data);
});
}
private void findViews() {
mTvShare1 = findViewById(R.id.tv_share_1);
mBtnShare1 = findViewById(R.id.btn_share_1);
}
}
public class DataShareTwoActivity extends AppCompatActivity {
private TextView mTvShare2;
private Button mBtnShare2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_two);
findViews();
mBtnShare2.setOnClickListener(v -> {
ShareLiveData.getInstance().setValue(new ShareModel("Second Page Back To Me"));
onBackPressed();
});
ShareLiveData.getInstance().observe(this, (value) -> {
if(value == null){
return;
}
mTvShare2.setText(value.data);
});
}
private void findViews() {
mTvShare2 = findViewById(R.id.tv_share_2);
mBtnShare2 = findViewById(R.id.btn_share_2);
}
}
2、更改数据
Transformations.map()
//Transformations.map() 在LiveData对象分发给观察者之前对其中存储的值进行更改
LiveData<Object> map = Transformations.map(shareModelLiveData, new Function<ShareModel, Object>() {
@Override
public Object apply(ShareModel input) {
return input.data + " Transformation";
}
});
map.observe(this,(value)->{
Toast.makeText(DataShareActivity.this, value.toString(), Toast.LENGTH_SHORT).show();
});
3、数据监听
Transformations.switchMap()
//监听其中一个的数据变化,并能根据需要随时切换监听
switchData = new MutableLiveData<>();
LiveData<ShareModel> transformations = Transformations.switchMap(switchData, new Function<Boolean, LiveData<ShareModel>>() {
@Override
public LiveData<ShareModel> apply(Boolean input) {
if(input){
return shareModelLiveData;
}
return noShareModelLiveData;
}
});
noShareModelLiveData.observe(this,(value)->{
Toast.makeText(this, "No Share", Toast.LENGTH_SHORT).show();
});
transformations.observe(this,(value)->{
mTvShare1.append("\nSwitchMap -> "+value.data);
});
switchData.setValue(false);
noShareModelLiveData.setValue(new ShareModel("转换NoShare"));
shareModelLiveData.setValue(new ShareModel("转换Share"));
二、LiveData原理分析
1、observe
首先看一下相关时序图
shareModelLiveData.observe(this,observer)
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
// 注释 1
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 注释 2
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;
}
// 注释 3
owner.getLifecycle().addObserver(wrapper);
}
通过传递来的this,获取到 LifecycleRegistry , 获取到当前的状态,如果是DESTROYED,则不处理,在Activity组件走onDestroy时,组件状态将变成DESTROYED,具体Lifecycle 介绍可见
将 Observer 封装在 LifecycleBoundObserver 中,并放入 mObservers 中,最后再将封装后的wrapper对象放入Lifecycle,然后该组件就具备了观察生命周期的能力。
Lifecycle观察生命周期变化原理可见xxxx,在生命周期变化时,会回调Observer中的onStateChanged方法和标记了生命周期注解对应的方法,我们可以看下onStateChanged方法,如果有这个方法,生命周期变化时都会调用。
这里注意一下,在Acitivity的onCreate中执行完 LiveData.observe 后,会将观察者包装一下,然后添加到观察者集合中,注入ReportFrament,执行onActivityCreate方法,然后开始分发Lifecycle.Event.ON_CREATE事件,然后ON_START、ON_RESUME事件,界面显示完毕。
LifecycleObserver 子类 LifecycleBoundObserver
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 注释 1
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 注释 2
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
注释 1 处 ,当组件状态为DESTROYED时,会把该Observer组件移除,所以观察者处于DESTROYED时,不会收到消息通知。否则如注释 2 处,将调用父类ObserverWrapper的 activeStateChanged 方法,其参数 shouldBeActive() ,主要是判断当前State状态是否是STARTED、RESUMED
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
activeStateChanged()
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
// 注释 1
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
// 注释 2
if (mActive) {
dispatchingValue(this);
}
}
该方法主要根据Active状态和处于Active状态的组件的数量,来调用相关方法,状态不变则不处理。
通过对shouldBeActive分析,可以知道只有在STARTED、RESUMED状态时newActive 为true,其它为false,我们这里分析由false 到true的情况,即 newActive 为false、true。
如果newActive 为false ,由于mActive变量初始化是false,所以后面语句不执行,执行不到注释 1 处。
当newActive 从 false 到 true 时,刚开始的时候 mActiveCount是为 0 的,wasInactive为true ,mActiveCount 则从 0 变为 1,onActive方法执行,再执行dispatchingValue(this) 。然后newActive再由 true 到 false 时,wasInactive为false,mActiveCount从 1 到 0,只执行 onInactive 方法。
dispatchingValue(this)
void dispatchingValue(@Nullable ObserverWrapper initiator) {
//注释 1
//是否正在向观察者分发中 true 是
if (mDispatchingValue) {
//此次分发无效
mDispatchInvalidated = true;
return;
}
//正在分发
mDispatchingValue = true;
do {
//分发成功 分发有效
mDispatchInvalidated = false;
if (initiator != null) {
//注释 2
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
//分发完成
mDispatchingValue = false;
}
注释 2 处considerNotify 是真正通知观察者们,调用其onChanged方法 (代码分析直接写在代码中)
private void considerNotify(ObserverWrapper observer) {
//注释 1 重新判断组件 状态,也许他们改变了状态,非激活状态 啥也不干
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) { // 注释 2 重盘判断,也许状态改变了
observer.activeStateChanged(false);
return;
}
// 注释 3 mVersion为LiveData的成员变量,每次更新值,例如调用setValue时,会自增,这里判断主要是
//为了 当观察者进入了活动状态,但是我们并没有收到该事件,即setValue、postValue方法调用,最好不要回掉观察者的onChange方法
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked 注释 4 回掉观察者的 onChange 方法
observer.mObserver.onChanged((T) mData);
}
2、setValue
由于LiveData是个抽象类,我们分析它的子类MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
可以看到子类并没有做什么特别的操作,所以setValue还是LiveData进行处理的
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
注解 @MainThread 说明 setValue 必须在主线程调用, 其中 mVersion ++ 是用于版本比较,上一小节已经分析过,就是为了观察组件进入到活动状态,但是没有收到消息通知时,onChange方法回调。
dispatchingValue方法,之前分析过,唯一的区别就是这里参数是null,我们继续看一下
void dispatchingValue(@Nullable ObserverWrapper initiator) {
......
if (initiator != null) {
//注释 2
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//见上一小节分析
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
........
}
可以看到,如果传null的话,它会通知所有观察组件新消息,进行必要的onChange回调,观察组件是从哪里来的呢?之前一节对 observe() 方法分析时,知道mObservers会将所添加的观察者进行包装保存。
3、postValue
postValue同样是交给了LiveData类处理
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
与 setValue 不同的是,此方法可以在子线程调用,然后通过 ArchTaskExecutor 切换到主线程,执行 mPostValueRunnable
ArchTaskExecutor是怎么切换到主线程的呢?我们继续追踪ArchTaskExecutor类
@NonNull
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
从中可以看出 切换到主线程的功劳还是 DefaultTaskExecutor ,我们直接看它的postToMainThread方法,
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
可以清楚得看到是拿到主线程的Looper,利用Handler向主线程发送消息。
那切换到主线程后,是如何设置数据的呢?我们可以看一下发送的 mPostValueRunnable 消息
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
最终还是调用了setValue方法,也就是postValue 通过Handler切换到了主线程,然后调用setValue方法。
2、Transformations.map
@MainThread //主线程
public static <X, Y> LiveData<Y> map(@NonNull LiveData<X> source,
@NonNull final Function<X, Y> func) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(func.apply(x));
}
});
return result;
}
MediatorLiveData 是 MutableLiveData 的子类,直接看其addSource方法
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
首先会将外部传入的LiveData 对象 和 构建的观察者 提供给Source对象 e。然后放入到 mSources (SafeIterableMap) 中。
之前分析过,LiveData添加了观察者后,会拥有观察生命周期的能力,可以看之前分析的 activeStateChanged() 方法,组件活动状态,则mActiveCount = 1,因此 hasActiveObservers() 为 true,但是在之前的示例中,onCreate 里面 执行 Transformations.map ,这里是false的,不信,可以打个断点试试。
addSource() 方法调用完后,返回 MediatorLiveData ,然后调用 observe 方法 将观察者包装一下,添加到Lifecycle中。
那什么时候触发mSouces里 存放的 Source对象中观察者的onChanged方法呢?即 下面 这个 new Observer 的 onChange方法
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(func.apply(x));
}
});
当这个onChange 方法调用后,通过 result.setValue 才能触发 你在 Activity 中 写的观察者,即之前示例代码DataShareActivity onCreate 中的观察者。
map.observe(this,(value)->{
Toast.makeText(DataShareActivity.this, value.toString(), Toast.LENGTH_SHORT).show();
});
回到onChanged调用时机问题,我们跟踪mSources对象,发现MediatorLiveData 复写了父类的onActive和onInactive方法,内部对mSources 进行了遍历并执行了相应的方法。换句话说,是我们在Activity onCreate 中的 Transformations.map 对 mSources 添加了相应的 LiveData 和 Source 对象,然后 会执行 LifecycleBoundObserver 的 onStateChanged 方法(这里开头分析过了),然后会执行相应的onActive 和 onInactive 方法,组件活动状态下看 onActive 方法即可。
onActive()
@CallSuper
@Override
protected void onActive() {
for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
source.getValue().plug();
}
}
source.getValue().plug()方法
void plug() {
mLiveData.observeForever(this);
}
observeForever()
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
//注释 1
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//注释 2
wrapper.activeStateChanged(true);
}
其中注释 1 处的AlwaysActiveObserver 和 LifecycleBoundObserver 不一样的地方在于 shouldBeActive 返回值,前者是固定的 true,永远是活动状态。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
注释 2 调用的是ObserverWrapper的activeStateChanged方法,之前已经讲解了,会回调观察者的 onChanged方法。
3、Transformations.switchMap
switchMap和map类似,此处不过多分析,在代码内进行讲解
@MainThread
public static <X, Y> LiveData<Y> switchMap(
@NonNull LiveData<X> source,
@NonNull final Function<X, LiveData<Y>> switchMapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
LiveData<Y> mSource;
@Override
public void onChanged(@Nullable X x) {
// 注释 1 可以看前面的示例,这里 switchMapFunction.apply(x) 得到一个LiveData
LiveData<Y> newLiveData = switchMapFunction.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
// 注释 2 先移除前一个LiveData 构建的 Source
result.removeSource(mSource);
}
//注释 3 重新赋值
mSource = newLiveData;
if (mSource != null) {
//注释 4 添加Source
result.addSource(mSource, new Observer<Y>() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}