Lifecycle 能够感知宿主生命周期变化的组件
基于生命周期消息分发订阅的能力,向当前宿主LifecycleOwner 注册一个observer ,宿主每一次生命周期的变化都会回调给观察者的onStateChanged方法,即便是刚刚注册的观察者,宿主也会回调它的onStateChanged方法,会有状态同步的过程
LiveData 利用了这个能力,巧妙的实现了当宿主销毁的时候自动移除自动注册进来的observer ,从而避免了手动注册的麻烦,不会造成内存泄漏
LiveData组件是Jetpack新推出的基于观察者的消息订阅/分发组件,具有宿主(Activity、Fragment)生命周期感知能力,这种感知能力可确保 LiveData 仅分发消息给处于活跃状态的观察者,只有处于活跃状态的观察者才能收到消息
活跃状态:0bserver所在宿主处于started,resumed状态
handler发送消息:
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg){
};
handler.sendMessage(msg)
LiveData:
liveData,observer(this,new Observer){
void onChanged(User user){
}
}
liveData.postValue(data);
使用继承自LiveData的MutableLiveData做消息分发,使用单一开闭原则,只有MutableLiveData擦可以发送消息
LiveData 对象只能接收消息,避免拿到 LiveData 对象时既能发消息也能收消息的混乱使用
public class MutableLiveData extends LiveData {
@Override
public void postValue(T value){
super.postValue(value);
}
@0verride
public void setValue(T value) {
super.setValue(value);
}
}
可以统一观察多个LiveData发射的数据进行统一的处理,同时也可以做为一个LiveData,被其他Observer观察
LiveData liveDatal = new MutableLiveData();
LiveData liveData2 = new MutableLiveData();
MediatorLiveData liveDataMerger = new MediatorLiveData<>(),
liveDataMerger.addSource(liveData1, observer);
liveDataMerger,addSource(liveData2, observer);
Observer observer = new Observer(){
@0verride
public void onChanged(@Nullable Integer s){
mTv.setText(s):
}
}
可以对livedata的进行变化,并且返回一个新的livedata对象
MutableLiveData data = new MutableLiveData<>();
//数据转换
LiveData transformData = Transformations,map(data, input -> String.valueOf(input)
//使用转换后生成的transformData去观察数据
transformData.observe(this, output -> {
});
//使用原始的livedata发送数据
data.setValue(10);
即新注册的observer也能接收到前面发送的最后一条数据
即调用postValue,setValue才会触发消息的分发
调用observe方法将传递进来的observers对象包装成了一个LifecycleBoundObserver对象
然后保存到mObservers这个Map集合中,有消息时遍历这个集合去分发
调用observerForever方法会被包装成AlwaysActiveObserve对象,
LifecycleBoundObserver:具有生命周期感知的观察者,是LifecycleEventObserver 的子类
AlwaysActiveObserve:在他的方法里shouldBeActive 永远为true,不管宿主是否处于可见状态,都可以接收数据,处理场景,即便是在后台也要处理一些事情,一定要在宿主被销毁时进行反注册
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
// 若LifecycleOwner被销毁,则忽略该observer
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
// 将LifecycleOwner和Observer封装成具有生命周期感知的LifecycleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 避免重复添加相同的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;
}
// 把这个LifecycleBoundObserver对象注册到Lifecycle宿主的生命周期里
owner.getLifecycle().addObserver(wrapper);
}
// 无视生命周期, 每次数据发生变化时,都会回调通知 Observer
// 需要手动在不需要时移除 Observer
@MainThread
public void observeForever(@NonNull Observer observer) {
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;
}
wrapper.activeStateChanged(true);
}
然后把这个LifecycleBoundObserver对象注册到Lifecycle宿主的生命周期里,这个对象就能接收到宿主生命周期变化事件,每一次事件的通知都会回调到LifecycleBoundObserver的onStartChanged方法
//LiveData的内部类
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver{
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
//组件生命周期状态为活跃时只有2种情形,started和resume
//观察者是否活跃相当于宿主是否活跃,也就是宿主的状态是否大于等于STARTED;
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//当接收到宿主生命周期的DESTROYED 事件时会自动解除跟 owner 的绑定
//所以我们不用去手动移除观察者
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//宿主的状态发生了变化时,此时会判断宿主是否处于活跃状态,
//如果页面不处于活跃状态,即使状态改变,此时也不会被分发,可以避免后台任务抢占资源,当页面重新处于活跃状态才会分发。
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
首先会判断状态是否等于DESTROYED,如果宿主被销毁了,调用removeObserver(mObserver)主动执行反注册,从LiveData中把这个observer 移除掉,主动避免了内存泄漏的问题
如果宿主没有被销毁,宿主状态发生别的变化,就会触发activeStateChanged方法,并且通过shouldBeActive 方法判断观察者是否处于活跃的状态,也就是判断当前宿主是否处于活跃状态,是否处于可见状态
shouldBeActive:
Lifecycle 的 STATE 为 STARTED/RESUMED 则返回 true,表示处于活跃状态
void activestateChanged(boolean newActive){
if(newActive == mActive){
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount = 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if(wasInactive && mActive){
onActive();
}
if(LiveData.this.mActiveCount == 0 && !mActive){
onInactive();
}
if (mActive){
dispatchingValue(initiator: this);
}
}
在activeStateChanged方法中,首先判断activeCount是否等于0,如果等于0就说明LiveData 中没有任何的观察者处于活跃状态,
如果当且仅当有一个观察者的时候就会触发onActive 方法,
如果没有任何一个活跃的观察者就会触发onInactive方法,
当前观察者处于活跃状态,就会调用dispatchingValue 进行数据分发,把自己传递了进去
首先判断传递的参数是否为空,不为空就把数据分发给自己,如果为空,就是从setValue过来的,说明有了新的数据,此时需要把Observers 集合中所有的观察者进行遍历,把数据分发给它们
最终都会调用considerNotify 做真正的分发
//1、在宿主生命周期发生变化的时候。回调LifecycleBoundObserver的onStateChanged方法。最后会调到这个方法,传入this(LifecycleBoundObserver)
//2、在setValue的时候调用。传入null;
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 当前正在处于分发数据中 直接return,继续之前的分发
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//宿主生命周期状态变化initiator != null; setValue时initiator = null;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//迭代通知每个符合条件的观察者,调用considerNotify进行分发
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
先根据shouldBeActive判断观察者是否处于活跃的状态,也就是宿主是否可见
接着判断observer 的lastVersion是否大于等于LiveData的version 避免数据的重复发送,每次生命周期的变化都会走到这里,但是LiveData 发送几次,每个观察者就能接收几次,不然就会重复了
如果条件都满足就会执行observer包装的mObservers的onChanged方法,并对齐observer的lastVersion和LiveData的version字段
private void considerNotify(ObserverWrapper observer) {
// 如果当前不是处于活跃状态,就停止
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//判断观察者的最新版本号是否不小于LiveData的当前版本号
if (observer.mLastVersion >= mVersion) {
return;
}
//将livedata的version赋值给observer的version
observer.mLastVersion = mVersion;
// 回调出去
observer.mObserver.onChanged((T) mData);
}
PostValue 中需要用到handler post 到主线程,最终调用setValue
在这个方法中会讲LiveData 的version 字段+1
接下来调用dispatchChangeValue 并传递null
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
把注册进来的Lifecycle包装成LifecycleBoundObserver储存起来,然后利用Lifecycle的能力,当宿主的状态发生变化时都会回调LifecycleBoundObserver的onStateChanged 方法,在这里就会去判断每个观察者是否处于活跃状态,
对于使用Observer 方法注册的观察者而言是否处于活跃状态就相当于宿主是否处于活跃状态,如果使用ObserverForever注册的观察者,会一直处于活跃状态,即便页面处于不可见了,它也能够接收到数据。
LiveData 不仅能满足现有的事件分发能力,还能实现高性能的事件分发机制
LiveData 的version字段和Observer 的lastVsesion 字段,默认情况下在刚开始创建时都等于-1 ,如果liveData 已经发送了数据,它的version就会加1,这个时候如果新注册这个Observer 在触发消息分发的时候,这两个version 字段就不相等了,这个Observer 就能接收到之前发送的消息