上篇博客分享了下Lifecycle,使用的技术也就是:观察者模式+注解+反射。本篇博客继续学习Jetpack的LiveData,其实这个东西是一种可观察的数据存储类。
LiveData自己可以作为观察者,观察到数据变化,并回调给开发者。 它是可以监听到Activity(Fragment)生命周期的变化,并且在Activity处于活跃状态下,才发送时间通知开发者处理业务逻辑。
LiveData官网
这个LiveData不是数据,是数据存储类。
示例:一个按钮,一个TextView , 点击一个按钮,TextView的值+1。
LiveData一般是结合ViewModel使用的,关于ViewModel,之后的博客再分享。 先创建一个类继承自ViewModel:
/**
* author: liumengqiang
* Date : 2020/5/14
* Description :
*/
public class NameViewModel extends ViewModel {
//MutableLiveData继承自LiveData
private MutableLiveData name;
//暴露获取方法
public MutableLiveData getName() {
if(name == null) {
name = new MutableLiveData<>();
}
return name;
}
}
使用的话就很简单了, 在Activity的onCreate方法中:
private int index = 0;
private TextView nameTextView;
private Button btn;
private NameViewModel nameViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_data);
//获取或者创建ViewModel
nameViewModel =
new ViewModelProvider(this,
new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(NameViewModel.class);
//绑定LiveData到一个观察者上
nameViewModel.getName().observe(this, new Observer() {
@Override
public void onChanged(String s) {
nameTextView.setText(s);
}
});
nameTextView = findViewById(R.id.live_data_text);
btn = findViewById(R.id.live_data_btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//数据源改变
String name = "hello world " + (index ++);
nameViewModel.getName().setValue(name);
}
});
}
这个代码就很简单了,结果如下图:
这个例子是很简单的,LiveData强大之处就是: 既可以作为观察者,也可以作为被观察者。
作为观察者:能够感知Activity或者Fragment的生命周期的变化。
作为被观察者:当数据改变能够通知给开发者,以处理业务逻辑。
其内部原理是怎样的呢?
在分析源码之前我们看三个结论,
首先我们从订阅开始:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
//检测是否在主线程
assertMainThread("observe");
//判断组件是否是DESTROYED状态。
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将组件和Observer封装成一个对象:LifecycleBoundObserver
//这个对象实现了LifecycleObserver接口
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//把所有的Observer和封装的对象添加到了集合中
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
......
//这个是把LifecycleObserver实现对象和 组件绑定起来
//这样就能够感知组件的生命周期了。
owner.getLifecycle().addObserver(wrapper);
}
这里做了主要三件事
现在看下setValue方法,也就是改变LiveData里面的数据源
//从这个注解可以看出来必须要在主线程调用
@MainThread
protected void setValue(T value) {
// 检测是否在主线程
assertMainThread("setValue");
//定义了一个版本号
mVersion++;
//将值赋值给mData变量
mData = value;
//开始分发数据事件
dispatchingValue(null);
}
代码注释比较清晰了,主要是这个版本号:mVersion是个什么东西呢? 为什么定义这个东西呢? mVersion就是记录一下改变次数,每次setValue方法调用,也就是每次数据源改变,mVersion都会+1, 这个值接下来会和LifecycleBoundObserver实现类的mLastVersion对比的,具体下文解释。
然后将value值赋值给了mData对象,这样的话,试想一下,如果若此调用setValue方法,每次set 的值都不一样,那么是不是mData存储的都是最后一次setValue的值呢? 答案是肯定的,存储的就是最后一次setValue的值。
然后现在开始分发数据源改变的事件:
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
........
do {
mDispatchInvalidated = false;
if (initiator != null) {
//initiator不是null, 也就是定向分发事件,
considerNotify(initiator);
initiator = null;
} else {
//initiator是null
// 循环之前map, 然后给每个观察者都分发事件
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
由于此时传入的dispatchingValue传入的参数是null,所以是全部的观察者都分发事件。
传入initiator不是null的情况是在生命周期改变的情况下执行的,下文具体分析
private void considerNotify(ObserverWrapper observer) {
//判断是否是处于活跃状态
//是否是已经解绑
if (!observer.mActive) {
return;
}
//活跃状态是:STARTED或者RESUMED
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//判断Observer的mLastVersion和mVersion的大小
if (observer.mLastVersion >= mVersion) {
return;
}
//给Observer的mLastVersion重新赋值
observer.mLastVersion = mVersion;
//noinspection unchecked
//执行观察者的onChaned回调
observer.mObserver.onChanged((T) mData);
}
这里的ObserverWrapper observer对象实际上就是LifecycleBoundObserver, 这个在刚开始订阅的时候内部创建的。它继承自ObserverWrapper
LifecycleBoundObserver也实现了GenericLifecycleObserver,而GenericLifecycleObserver继承自LifecycleEventObserver, 这个细节很重要,具体后续的代码会着重分析。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {
super(observer);
mOwner = owner;
}
//判断是否是活跃状态:STARTED或者RESUMED,
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//这个方法就是组件生命周期改变时, 调用的方法。传入的参数一个是组件本身,一个是组件处于的状态
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//当组件处于DESTROYED状态时,也就是处于销毁状态时
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//移除Observer,解除绑定
removeObserver(mObserver);
return;
}
//这个方法的实现是在父类ObserverWrapper中的
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
从LifecycleBoundObserver的具体实现,需要注意两个知识点
在onStateChanged方法中调用了父类的activeStateChanged方法,看下具体实现:
void activeStateChanged(boolean newActive) {
//判断活跃状态是否等于上一次的状态
if (newActive == mActive) {
return;
}
......
//
if (mActive) {
//如果是活跃状态,那么就分发数据源改变事件,传入的参数是自己本身,
//也就是:LifecycleBoundObserver类的对象
dispatchingValue(this);
}
}
}
这时候对于dispatchingValue方法传入的参数不是null, 是不是就是单次分发呢? 懵逼的,重新网上看下dispatchingValue方法。,进入到了if判断里面。
重新回到considerNotify方法,mLastVersion和mVersion的初始值都是-1, 但是每次setValue, mVersion的值都会+1, 但是mLastVersion的值还是-1, 所以(observer.mLastVersion >= mVersion) 不成立,将mVersion的值赋值给mLastVersion, 这样mLastVersion就是最新的值了, 最后调用了我们熟悉的onChanged方法。
想一下considerNotify方法中为什么会有这三个if判断呢?
首先前两个判断就是要保证组件处于活跃状态; 此三个判断就是要保证只接受最后一次的新数据,并且只执行一次。 Google这样设计也是相当的巧妙!
这样每次setValue 到 执行onChange方法流程就分析完了。
那么它是怎样感知生命周期的呢? 换句话说就是LifecycleBoundObserver的onStateChanged方法是什么时候执行的呢?
这个问题,如果是看过Lifecycle源码的,这个问题是相当简单的。
Lifecycle源码分析
记不记得我们刚开始调用LiveData的observe方法的时候,该方法的最后一句话:
owner.getLifecycle().addObserver(wrapper);
把封装成的LifecycleBoundObserver类对象和组件绑定到了一块, 这样内部就通过 ReportFragment就能够感知生命周期的变化了。详见:Lifecycle源码分析
这里需要注意的一点是,当生命周期变化的时候,最终调用的dispatchEvent方法:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//这里返回的直接是将observer转成了LifecycleEventObserver。
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//调用了观察者的onStateChanged方法
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
这里的observer参数就是LifecycleBoundObserver类对象,上文说过LifecycleBoundObserver实现了LifecycleEventObserver接口,Lifecycling.lifecycleEventObserver(observer);
内部执行一通逻辑之后,做的操作是直接将observer转成了LifecycleEventObserver接口对象。
ReportFragment生命周期的变化之后,调用的是LifecycleBoundObserver的onStateChanged方法,这样是不是形成了闭环?!
重新理一下步骤:
setValue ——> onChanged流程
感知LiveData生命周期流程
dispatch(Lifecycle.Event.ON_START);
这样整个流程就完全了, 可能感知生命周期的流程比较懵逼的话,一定要看一下:Lifecycle源码分析