Android LiveData我的理解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/alcoholdi/article/details/97259805

LiveData用大众语言来来讲,是一个观察者,也是一个数据持有类或者可以称为一个数据的包裹类。它有别于其他的观察者的重点是,他具有生命周期感知能力,这里生命周期指的是activities, fragments, or services 的生命周期。

讲到LiveData,就想到DataBinding,想到MVVM。LiveData的确一开始是为这种模式而设计出来的。LiveData搞懂,可以说了解了MVVM的一半了。

 

说到LiveData拥有生命周期感知能力,那么如何实现。自己手写代码在onCreate、onStart、onResume这些方法里加入逻辑当然是一种方法,但这不够灵活不够解耦。所以在Android Support Library 26.1.0 开始,引入Lifecycles。

那么Lifecycles是什么?

可以理解为一个库或一堆类,加上在Activity、Fragment里面插入的一些逻辑代码,最终实现的生命周期可以通知到外界的体系。

 

像观察者模式一样。可以分为注册、反注册、发送事件和接受事件这4部分。

先来看发送部分。

发送部分(处于源码里面)

上面这个图以 android.support.v4.app.Fragment.java 为例,可以看到从8.1.0开始,在 performCreate、performStart、performResume、performPause、performStop 和 performDestroy 等方法都加上了发送生命周期 Event 事件。

 

Activity 发送生命周期 Event 会复杂一点,是在 android.support.v4.app.SupportActivity 里通过创建一个 ReportFragment,把在各个生命周期中发事件的代码逻辑挪进去 ReportFragment 里实现的。

这一招数让我想起了 Glide 对于图片生命周期的管理。Glide.with(Activity) 也是让 Activity 创建出一个 Fragment ,在 Fragment 的各个生命周期方法内插入回调函数后,执行代码来实现的。

SupportActivity.java(support库)
------------------------------
    @Override
    @SuppressWarnings("RestrictedApi")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }


ComponentActivity.java(androidx库)
------------------------------
    @Override
    @SuppressWarnings("RestrictedApi")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }


ReportFragment.java
------------------------------
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }

Activity 和 Fragment 都会调用到 LifecycleRegistry.handleLifecycleEvent(event) 方法。

LifecycleRegistry 是在 ComponentActivity 和 Fragment 中声明并且直接new出来的成员变量。

同时它们还是实现了 LifecycleOwner 接口,里面的 getLifecycle() 就是返回这个 mLifecycleRegistry 用的。

SupportActivity.java(用于support库)
------------------------------
public class SupportActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


ComponentActivity.java(用于androidx库)
------------------------------
public class ComponentActivity extends Activity
        implements LifecycleOwner, KeyEventDispatcher.Component {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


Fragment.java
------------------------------
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner {

    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);





LifecycleOwner.java
------------------------------
public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

用了 LifecycleRegistry 来管理注册到Activity或Fragment来的所有观察者。包括添加、删除观察者,接受生命周期事件并分发到各个观察者中。

LifecycleRegistry 会维护一个 State 变量。同时这些观察者 ObserverWithState 也会有维护一份属于自己的声明周期状态 State。

这两份 State 的作用是,两者比较后,可以决定观察者列表「从前往后遍历」还是「从后往前遍历」。为什么要分「从前往后遍历」还是「从后往前遍历」我猜可能是一些观察者要遵循栈的后进先出原则吧,后注册的一些观察者组件需要先进行反注册操作。

 

下面这图是Lifecycles体系里面 State 和 Event 的关系。

 

 

LifecycleRegistry.handleLifecycleEvent(event) 之后接着是

 LifecycleRegistry.sync() 方法,接着是

backwardPass() 或者 forwardPass(),代表从后往前遍历还是从前往后遍历。

在里面会遍历 LifecycleRegistry 的成员变量 mObserverMap,这个 Map 就是该 Activity/Fragment 生命周期的观察者。遍历 Map 后逐个调用 ObserverWithState.dispatchEvent(),最后执行 GenericLifecycleObserver.onStateChanged()。即逐个通知到观察者,当前 Activity/Fragment 处于哪个生命周期里了。

 

注册、反注册和接受通知(处于源码外面,需要开发者写)

说完发送生命周期通知事件后,就该讲在外面我们如何使用观察者监听通知了,包括注册、反注册和接受通知。

简单写法一般有这么两种,这是第一种,注解声明只接受 ON_RESUME 事件通知

这是第二种

注册后可以成功收到相应事件。看logcat日志,我把一个MainActivity打开又关闭后,输出了这些日志。

ps:GenericLifecycleObserver 下面报红了,因为这个类上面的注解说明了,这个类只应该在自己的library 里面使用。可以忽略这个警告。看 GenericLifecycleObserver 头像的注解,如下图

 

LiveData

下面要讲回LiveData了,文章一开始介绍了了LiveData是什么。它是一个基于观察者模式的数据的包裹类,最重要的特点是生命周期感知能力。

怎么实现生命周期感知能力,其实就是内部帮我们封装了 Lifecycles 的「注册」、「反注册」和「接受生命周期事件,并且做出相应处理」的代码。

下图是 LiveData 的基本使用。

LiveData 执行 observe() 方法后,传入当前 Activity 和 回调方法。

注册(LiveData的注册生命周期)

LiveData.java
------------------------------
    @MainThread
    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;
        }
        
        //通过activity获取LifecycleRegistry,将回调方法封装成一个LifecycleBoundObserver传进去
        owner.getLifecycle().addObserver(wrapper);
    }

可以看到,LiveData 里面的注册 Lifecycles 流程在这个 observe 方法里。

owner.getLifecycle() 就是在 Activity/Fragment 中获取到 LifecycleRegistry。将回调方法封装成一个 LifecycleBoundObserver 实体后注册到 Activity/Fragment 的功能。

 

反注册(LiveData的反注册生命周期)

LifecycleBoundObserver 中提供了一个 detachObserver() 方法,只有这个方法里面,会进行生命周期的反注册功能。

    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        //判断如果不是主线程则抛异常
        assertMainThread("removeObserver");

        //mObservers 是属于这个 LiveData 的观察者集合,需要从集合里删除这个观察者
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }

        //这个 removed 变量的声明是 ObserverWrapper 类型。这是个抽象类,无法实例化。
        //实际只能是 AlwaysActiveObserver 或者 LifecycleBoundObserver 两种类型。
        //1.如果是 AlwaysActiveObserver 类型,没有重写 detachObserver() 方法。
        //因为这是属于 observeForever 的逻辑,永久观察当然不用处于声明周期方面的功能。
        //2.如果是 LifecycleBoundObserver 类型,则重写了 detachObserver() 方法。
        //用于让 owner 移除这个观察者。
        removed.detachObserver();
        
        //因为移除了一个观察者,可能使得 LiveData 的活跃观察者从1变0,所以需要通知一下。
        removed.activeStateChanged(false);
    }

    @SuppressWarnings("WeakerAccess")
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }


    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

这里的 detachObserver() 方法在 LiveData.removeObservers(Observer<T>) 和 LiveData.removeObservers(LifecycleOwner) 中调用的。

LiveData.removeObservers(LifecycleOwner) 内部也是调用的 LiveData.removeObservers(Observer<T>)。让我们先捋清楚 removeObserver(Observer<? super T>) 干了些什么事情。

干得四件事如代码注释所写。

那么 LiveData.removeObservers(Observer<T>) 在什么时候调用呢?

LiveData.removeObservers(Observer<T>) 其实是在接受生命周期回调的 onStateChanged(LifecycleOwner, Lifecycle.Event) 方法中,会判断如果是如果当前 owner 处于 DESTROYED 状态就执行。LiveData 是用的此种方法让它具有了自动反注册功能。下面请看 LiveData 如何接受生命周期事件。

 

 

接受生命周期事件并且做出相应处理

LifecycleBoundObserver.java
------------------------------
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }


ObserverWrapper.java
------------------------------
private abstract class ObserverWrapper {

    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(this);
        }
    }

我们知道 LifecycleOwner 发送的生命周期事件会经过层层调用,最后到 GenericLifecycleObserver.onStateChanged(LifecycleOwner, Lifecycle.Event)。

在这里体现在子类 LifecycleBoundObserver.onStateChanged(LifecycleOwner, Lifecycle.Event)。

方法里第一步会判断是 DESTROYED 事件则进行 LiveData 反注册方面的操作。

第二步是调用了 ObserverWrapper.activeStateChanged(boolean) 方法。

 

方法里传了一个布尔值,表示当前 owner 的是否处于 Active 活跃状态。在这里意思是 State 为 STARTED 或 RESUMED 才算活跃。以后会讲到某些子实现类会重写这个 shouldBeActive() 方法,来写不同的判断是否活跃的逻辑。

方法里判断,如果当前状态 和 新传进来的状态一样,直接 return 了。只有不一样才会往下执行。

第一步是让当前这个 Observer 缓存当前的 Active 状态,供以后用到。

第二步会修改 mActiveCount 变量,表示当前 LiveData 所关联的 owner 有多少个是活跃的。

第三步是根据之前的 Active 状态,和新传进来的 Active 状态,判断是否需要执行

LiveData.onActive()  活跃观察者数量从0变成1

LiveData.onInactive()  活跃观察者数量从1变成0

以及最重要的第四步!这里调用了 dispatchingValue(this), this 指的是 LifecycleBoundObserver 实体。意思是

如果是状态是从不活跃到活跃,则立即派发事件到这个观察者中。达到的就是 粘性广播 或 粘性EventBus 那样的效果。

也意味着,一个 LiveData 如果已经有设置过数据,添加进一个观察者后会立刻执行一次观察着的回调方法。

因为添加进一个新观察者,就是新观察者内部就是从不活跃到活跃的过程。

关于派发事件 dispatchingValue 方法留到下面讲。

以上就是 LiveData 封装好的 Lifecycles 的「注册」、「反注册」和「接受生命周期事件,并且做出相应处理」的代码。

 

下面讲下 LiveData 关于数据方面的操作,包括修改数据 和 数据修改后的回调操作(比如 DataBinding 的更新UI操作)。

开发者如何使用 LiveData 

LiveData.java
------------------------------
    @MainThread
    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);
    }

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

    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() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

    @Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            //noinspection unchecked
            return (T) data;
        }
        return null;
    }

observe(LifecycleOwner, Observer<? super T>) 是在 LiveData 里注册一个观察者,如果数据发生变化会通知这些观察者。

setValue(T) 用于在主线程里面修改数据

postValue(T) 用于在子线程里面修改数据,当然最终还是会调到到 setValue(T) 

getValue(T) 就是get方法很好理解吧,在简单流程里使用是不需要用到的,像在Android DataBinding架构里才会用到。

setValue(T) 最终调用到 dispatchingValue()

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                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;
    }

    private void considerNotify(ObserverWrapper observer) {
        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()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

dispatchingValue(null) 里对观察者集合 mObservers 进行遍历,执行 considerNotify 方法。

相比起刚才的粘性通知的 dispatchingValue(this) 是通知传进来的单个观察者。这里就是遍历全通知到了。

consider 这单词用得好啊,考虑要不要通知。

considerNotify 方法里,会修改 LifecycleBoundObserver 的活跃状态,判断当前 LifecycleBoundObserver 的版本号。

最终调用到 Observer.onChanged(T) 方法。也就是我们使用 LiveData 一开始传进来的回调函数。

 

如果我们按了 home 键回到桌面呢?

回到桌面,会让我们的 owner (Activity&Fragment) 执行 onPause 和 onStop 方法。

前面讲到,这会让观察者接受到生命周期时间,层层调用触发到每个 Observer 的 activeStateChanged 方法里。在这里把 Observer 的 mActive 状态置为 false。

然后在 considerNotify(ObserverWrapper) 开头,会判断这个 Observer 是不是处于不活跃状态。如果是不活跃状态就直接返回了。

这样就达到了只有在 LifecycleOwner 处于 Active 状态 (STARTED 或 RESUMED) 下才会下发事件通知的效果

 

 

这就是 LiveData 实现数据更新就回调,并且关联生命周期的基本流程。

除此之外,还有不关联生命周期的 observeForever 方法。

LiveData.java
------------------------------
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        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);
    }

    private class AlwaysActiveObserver extends ObserverWrapper {

        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

MutableLiveData 继承自 LiveData,把setValue(T) 和 getValue(T) 方法public公开了。

最终使用 LiveData 修改数据,就像这样使用 setValue 就可以。

 

总结 LiveData 的3个重要能力。

1.检测到 LifecycleOwner 变成 DESTROYED 后,自动移除 Observer 回调。

2.从 非Active 到 Active 转变,观察者 Observer 会自动获取最新数据+触发回调,达到  粘性Sticky 效果。

3.判断如果处于 非Active 状态,就不触发 Observer 回调,节约CPU资源。

 

 

LiveData 推出来是为了实现谷歌的 DataBinding,实现 MVVM 架构。

然而后面一些第三方库也开始使用这个强大的 LiveData 工具了。

比如说 LiveEventBus 。

https://github.com/JeremyLiao/LiveEventBus

LiveEventBus

先简单看看 LiveEventBus 是怎么使用 LiveData 的。

public final class LiveEventBus {

    public synchronized <T> Observable<T> with(String key, Class<T> type) {
        if (!bus.containsKey(key)) {
            bus.put(key, new LiveEvent<>(key));
        }
        return (Observable<T>) bus.get(key);
    }

    private class LiveEvent<T> implements Observable<T> {

        private final LifecycleLiveData<T> liveData;

        LiveEvent(@NonNull String key) {
            this.key = key;
            this.liveData = new LifecycleLiveData<>();
        }

        @Override
        public void observe(@NonNull final LifecycleOwner owner, @NonNull final Observer<T> observer) {
            if (ThreadUtils.isMainThread()) {
                observeInternal(owner, observer);
            } else {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        observeInternal(owner, observer);
                    }
                });
            }
        }

        @MainThread
        private void observeInternal(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
            ObserverWrapper<T> observerWrapper = new ObserverWrapper<>(observer);
            observerWrapper.preventNextEvent = liveData.getVersion() > ExternalLiveData.START_VERSION;
            liveData.observe(owner, observerWrapper);
        }

        @Override
        public void post(T value) {
            if (ThreadUtils.isMainThread()) {
                postInternal(value);
            } else {
                mainHandler.post(new PostValueTask(value));
            }
        }

        @MainThread
        private void postInternal(T value) {
            liveData.setValue(value);
        }

可以看到 LiveEventBus 那一行代码调用的 observe 方法,最终会使用到 LiveEvent 里面的 liveData 属性,让 liveData 属性调用 observe(LifecycleOwner, Observer<? super T>) 方法。

而 LiveEventBus 的发送事件,也是调用了 LiveData.setValue(T)。

 

LiveEventBus 它声称具有「生命周期感知,消息随时订阅,自动取消订阅」能力,那么怎么实现的呢?

我们前面讲到,如果生命周期发生变化,LifecycleOwner 会发出事件通知,在 GenericLifecycleObserver.onStateChanged(LifecycleOwner, Lifecycle.Event) 中能接受到回调。

LiveData.java
------------------------------
public abstract class LiveData<T> {

    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }
    }


    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        removed.activeStateChanged(false);
    }



LiveEventBus.java
------------------------------
public final class LiveEventBus {

    private class LiveEvent<T> implements Observable<T> {

        private class LifecycleLiveData<T> extends ExternalLiveData<T> {
            @Override
            protected Lifecycle.State observerActiveLevel() {
                return lifecycleObserverAlwaysActive ? Lifecycle.State.CREATED : Lifecycle.State.STARTED;
            }

            @Override
            public void removeObserver(@NonNull Observer<? super T> observer) {
                super.removeObserver(observer);
                if (autoClear && !liveData.hasObservers()) {
                    LiveEventBus.get().bus.remove(key);
                }
            }
        }

前面讲过在 LiveData 的内部类 LifecycleBoundObserver.onStateChanged 方法中会判断如果当前 state 是 DESTROYED,就删除观察者操作。这个要删除的观察者 Observer 是 LiveData 的所包裹的数据的观察者。

具体在 LiveData 代码的逻辑是,把这个observer 从 mObservers集合(LiveData 所缓存的一份观察者列表) 中移除。

 

对应到我们 LiveEventBus ,就是我们使用 LiveEventBus 传进去的 Observer 回调函数给移除了。

这样就实现了「自动取消订阅」的效果。


 

还有LiveEventBus声称具有「整个生命周期(从onCreate到onDestroy)都可以实时收到消息」能力,那么怎么实现的呢?

ps:这算值得写出来的能力吗?这不是一个正常的事件总线应有的能力吗?

ExternalLiveData.java
------------------------------
public class ExternalLiveData<T> extends MutableLiveData<T> {

    protected Lifecycle.State observerActiveLevel() {
        return CREATED;
    }

    class ExternalLifecycleBoundObserver extends LifecycleBoundObserver {

        ExternalLifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(owner, observer);
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(observerActiveLevel());
        }
    }



LiveEventBus.java
------------------------------
public final class LiveEventBus {

    private boolean lifecycleObserverAlwaysActive = true;

    private class LifecycleLiveData<T> extends ExternalLiveData<T> {
        @Override
        protected Lifecycle.State observerActiveLevel() {
            return lifecycleObserverAlwaysActive ? Lifecycle.State.CREATED : Lifecycle.State.STARTED;
        }



LiveData.java
------------------------------
public abstract class LiveData<T> {


    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

原生 LiveData.java 使用了 LifecycleBoundObserver,所以在判定是否活跃的这个 shouldBeActive() 方法中,owner 的生命周期 state ≥ STARTED 才会认为是活跃。即 STARTED 和 RESUMED。符合 MVVM 的特性,可见的界面才有必要更新UI。

LiveEventBus 如果使用这个策略是不太合理的,所以重写了 shouldBeActive() 方法,让它判断逻辑是≥CREATED(LiveEventBus的默认情况)即认为是活跃。达到了官网宣称的「整个生命周期(从onCreate到onDestroy)都可以实时收到消息」效果。

 

对于生命周期,另外更新了一篇博客《Android 关于监控生命周期的几种策略》。想了解的同学可以看看。

 

参考来源:

https://developer.android.com/topic/libraries/architecture/lifecycle

https://developer.android.com/topic/libraries/architecture/livedata

 

 

展开阅读全文

没有更多推荐了,返回首页