Android Jetpack架构组件之LiveData原理篇

LiveData的原理:使用了观察者设计模式,但是这个观察者是跟生命周期拥有者(Activity或Fragment)绑定了生命周期的,想要了解LiveData的原理,还要先理解Lifecycle的原理,因为里面表面是LiveData和Observer建立观察者模式,但实际最终还是LifecycleOwner和LifecycleObserver建立的观察者模式。

我这里先梳理一个各函数的流程:

注册的流程:

LiveData(observe)--->LifecycleRegistry(addObserver)--->ObserverWithState(dispatchEvent)--->LifecycleBoundObserver(onStateChanged)--->ObserverWrapper (activeStateChanged)--->LiveData(dispatchingValue)--->LiveData(considerNotify)--->Observer(onChanged)最终就到了数据的onChange回调了。

发送数据的流程:

LiveData(setValue)--->LiveData(dispatchingValue)--->LiveData(considerNotify)--->Observer(onChanged)

一、LiveData 核心方法:

1、LiveData 公开(public)方法

  1. T getValue()

  2. //返回当前值。请注意,在后台线程上调用此方法不能保证将接收到最新的值集。

  1. boolean hasActiveObservers()

  2. //如果此LiveData具有活动的观察者,则返回true。

  1. boolean hasObservers()

  2. //如果此LiveData具有观察者,则返回true。

  1. void observe(LifecycleOwner owner, Observer<T> observer)

  2. //(注册和宿主生命周期关联的观察者)将给定的观察者添加到给定所有者的生存期内的观察者列表中。

  1. void observeForever(Observer<T> observer)

  2. //(注册观察者,不会反注册,需自行维护)将给定的观察者添加到观察者列表中。

  1. void removeObserver(Observer<T> observer)

  2. //从观察者列表中删除给定的观察者。

  1. void removeObservers(LifecycleOwner owner)

  2. //删除所有与给定绑定的观察者LifecycleOwner。

2、LiveData 受保护(protected)方法

  1. void onActive()

  2. //(当且仅当有一个活跃的观察者时会触发)当活动观察者的数量从0变为1时调用。

void onInactive()
//(不存在活跃的观察者时会触发)当活动观察者的数量从1变为0时调用。
 
//这并不意味着没有观察者,可能仍然有观察者,但是它们的生命周期状态不是STARTED或RESUMED (如后退堆栈中的“Avtivity”)。
 
//您可以通过来检查是否有观察者hasObservers()。

  1. void postValue(T value)

  2. //(和setValue一样。不受线程环境限制,)将任务发布到主线程以设置给定值。

  1. void setValue(T value)

  2. //(发送数据,没有活跃的观察者时不分发。只能在主线程。)设置值。

二、LiveData 原理解析:

1、observe订阅源码分析

LiveData 注册观察者触发消息分发流程原理分析

1.1首先看看observe方法源码

observe 注册时,可以主动跟宿主生命周期绑定,不用反注册:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    //1. 断言,这个方法只能在主线程调用(如果不在主线程注册会抛IllegalStateException异常)
    assertMainThread("observe");
    //2.当前绑定的组件(activity或者fragment)状态为DESTROYED的时候, 则会忽视当前的订阅请求
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    //3.创建生命周期感知的观察者包装类(把注册进来的observer包装成 一个具有生命周边边界的观察者)
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    //4.接着会判断该观察是否已经注册过了,如果是则抛异常,所以要注意,不允许重复注册
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    //5.对应观察者只能与一个owner绑定
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    //6.利用Lifecycle,把观察者被实现了LifeCycleObserver的LifecycleBoundObserver再包装一层,就变成有生命周期变化的观察者了,然后addObserver注册到Lifecycle中,就能监听到宿主生命周期状态的变化
    owner.getLifecycle().addObserver(wrapper);
}

总结:

1、observe只能在主线程调用,如果不在主线程注册会抛IllegalStateException异常

2、当前绑定的组件(activity或者fragment)状态为DESTROYED的时候, 则会忽视当前的订阅请求

3、内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)

4、对应观察者只能与一个owner绑定,不允许重复注册

5、最后利用Lifecycle,把观察者注册到LifecycleBoundObserver进去,就能监听到宿主生命周期状态的变化

LifecycleBoundObserver到底承载了哪些信息,接着看...

1.2、LifecycleBoundObserver源码:
从上面的分析可以看出:

利用Lifecycle,把观察者注册到LifecycleBoundObserver进去,这样监听到宿主生命周期状态的变化

一旦一个新的观察者被添加,Lifecycle也会同步它的状态和宿主一致,此时会触发观察者的onStateChanged方法

内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)

它能监听宿主被销毁的事件,从而主动的把自己反注册,避免内存泄漏

此时观察者是否处于活跃状态就等于宿主是否可见, 监听宿主的生命周期,并且宿主不可见时不分发任何数据

LifecycleBoundObserver源码:
 

//1、LifecycleBoundObserver是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;
        //如果页面当前不可见,你发送了一条消息,此时是不会被分发的,可以避免后台任务抢占资源,当页面恢复可见才会分发。
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
 
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        //3、如果当接收到 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);
    }
}
 
//接口,触发观察者的onStateChanged方法
//通过Lifecycle,addObserver(Observer oberver)
//handleLifecycleEvent(Event event)
//宿主(Activity 或 Fragment)每次生命周期变化都会回调onStateChange方法
public interface LifecycleEventObserver extends LifecycleObserver {
    /**
     * Called when a state transition event happens.
     *
     * @param source The source of the event
     * @param event The event
     */
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

ObserverWrapper 状态变更后,如果观察者处于活跃状态会触发数据的分发流程

//抽象类
private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    //ObserverWrapper在每次注册的时候都会重新new,所以mLastVersion每次都是-1开始。
    int mLastVersion = START_VERSION;//这里就等于-1
 
    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer;
    }
 
    abstract boolean shouldBeActive();
 
    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }
 
    void detachObserver() {
    }
 
    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;
        //1、如果此时有且只有一个活跃的观察者则触发onActive
        if (wasInactive && mActive) {
            onActive();
        }
        //2、没有任何一个活跃的观察者则触发onInactive
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            onInactive();
        }
        //3、如果此时观察者处于活跃状态,下面就开始分发数据了
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

dispatchingValue(this)数据分发流程控制:(内部执行considerNotify(initiator)方法)

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            //1、如果传递的观察者不为空,则把数据分发给他自己。这个流程是新注册观察者的时候会被触发
            considerNotify(initiator);
            initiator = null;
        } else {
            //2、否则遍历集合中所有已注册的的观察者,逐个调用considerNotify,分发数据
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

considerNotify 数据真正分发的地方:

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.
    //2、观察者所在宿主是否处于活跃状态,否则不分发,并且更改观察者的状态为false
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    //3、此处判断观察者接收消息的次数是否大于等于 发送消息的次数(observer被创建之初verison=-1 )
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    //4、计算最新的发送消息的次数
    observer.mLastVersion = mVersion;
    //5、这里会执行传入的observer的onChanged方法
    observer.mObserver.onChanged((T) mData);
}

2、setValue发送源码分析

2.1 setValue源码分析

@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        //这个mVersion是属于LiveData的,然后只在setValue(postValue最终也会调用setValue)的时候会自增1
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

2.2同上observer分析,dispatchingValue(this)数据分发流程控制:(内部执行considerNotify(initiator)方法)

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            //1、如果传递的观察者不为空,则把数据分发给他自己。这个流程是新注册观察者的时候会被触发
            considerNotify(initiator);
            initiator = null;
        } else {
            //2、否则遍历集合中所有已注册的的观察者,逐个调用considerNotify,分发数据
            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.3、considerNotify 数据真正分发的地方:

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.
    //2、观察者所在宿主是否处于活跃状态,否则不分发,并且更改观察者的状态为false
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    //3、此处判断观察者接收消息的次数是否大于等于 发送消息的次数(observer被创建之初verison=-1 )
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    //4、计算最新的发送消息的次数
    observer.mLastVersion = mVersion;
    //5、这里会执行传入的observer的onChanged方法
    observer.mObserver.onChanged((T) mData);
}

综上分析:LiveData的粘性事件:

这种情况被称为LiveData的粘性事件

通过同一个LiveData

在更改数据的时候调用setValue(postValue最终也会调用setValue)的时候内部维护的mVersion会自增1,mVersion初始值是-1

在监听数据变化的时候,既调用observer监听的时候,每次内部都会在通过包装类中new ObserverWrapper,内部维护了一个mLastVersion变量,mLastVersion也是初始值为-1,所以注意了,每执行一次observer方法内部维护mLastVersion都会新创建而变为-1

结论所以只要之前有发射过一次数据,那么后面注册的观察者都会接收到之前发射过的数据

这也是为什么通常使用LiveData时,在大多数情况下,应用组件的 onCreate() 方法是开始观察 LiveData 对象的正确着手点,就是为了避免粘性事件的发生。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值