• Jetpack 热门组件 LiveData 的生命周期是如何变化的?


    LiveData 是什么?

    LiveData 是 Jetpack 推出的基于观察者的消息订阅/分发的可观察数据组件,具有宿主(Activity、Fragment)生命周期感知能力,这种感知能力可确保 LiveData 仅分发消息给处于活跃状态的观察者,即只有处于活跃状态的观察者才能收到消息

    LiveData 的事件分发机制,会根据监听者的活跃状态来判断是否分发数据源变化事件,这样的话,我们就能避免当前页面在后台时,响应了事件,做出一些无用的逻辑浪费性能

    LiveData 的简单使用

    LiveData 的使用十分方便,只需要简单的三步:

    1、创建 LiveData 对象,LiveData 是抽象类,所以需要创建它的子类 MutableLiveData;

    2、设置观察者 observe,第一个参数是 LifecycleOwner 对象,第二个是观察者监听,当数据改变的时候会在 onChanged 方法内做出响应;

    3、设置数据,通过 postValue 或者 setValue 方法来更新数据;

    LiveData 生命周期

    LiveData 如何观察组件生命周期变化

    通过调用 LiveData 的 observe 方法来注册观察者,LiveData 的 observe 方法如下所示

     @MainThread
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            assertMainThread("observe");
            //如果被观察者的当前的状态是DESTROYED,就return
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1
                return;
            }
            LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2
            ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3
            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);//4
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注释1处的 owner 实际上就是注册时传进来组件,比如 Activity,获取组件当前的状态,如果状态为 DESTROYED,那么直接 return,这说明 DESTROYED 状态的组件是不允许注册的

    注释2处新建了一个 LifecycleBoundObserver 包装类,将 ownerobserver 传了进去

    注释3处将 observer 和 LifecycleBoundObserver 存储到 SafeIterableMap, ObserverWrapper>mObservers

    • putIfAbsent 方法和 put 方法有区别

    如果传入 key 对应的 value 已经存在,就返回存在的 value,不进行替换。如果不存在,就添加 key 和 value,返回 null

    如果等于 null,在注释4处会将 LifecycleBoundObserver 添加到 Lifecycle 中完成注册,这样当我们调用 LiveData 的 observe 方法时,实际上是 LiveData 内部完成了 Lifecycle的观察者的添加

    • 这样 LiveData 自然也就有了观察组件生命周期变化的能力

    LiveData 的 observe 方法回调

    LifecycleBoundObservers是LiveData的内部类,代码如下所示

     class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
            @NonNull final LifecycleOwner mOwner;
    
            LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
                super(observer);
                mOwner = owner;
            }
    
            @Override
            boolean shouldBeActive() {
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    removeObserver(mObserver);//1
                    return;
                }
                activeStateChanged(shouldBeActive());//2
            }
    
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
    
            @Override
            void detachObserver() {
                mOwner.getLifecycle().removeObserver(this);
            }
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    LifecycleBoundObserver继承了ObserverWrapper类,重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态

    LifecycleBoundObserver实现了GenericLifecycleObserver接口,当组件状态发生变化时,会调用onStateChanged方法,当组件处于DESTROYED状态时,会调用注释1处的removeObserver方法,来移除observer

    这样就解决了,为什么一个观察者(组件)处于DESTROYED状态时,它将不会收到通知

    接着会调用注释2处的activeStateChange方法,代码如下所示

      private abstract class ObserverWrapper {
            final Observer<? super T> mObserver;
            boolean mActive;
            int mLastVersion = START_VERSION;
    
            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;
                }
                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);//1
                }
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    activeStateChanged方法定义在抽象类ObserverWrapper中,它是Observer的包装类,activeStateChanged方法会根据Active状态和处于Active状态的组件的数量,来对onActive方法和onInactive方法回调,这两个方法用于拓展LiveData对象

    注释1处,如果是Active状态,会调用dispatchingValue方法,并将自身传进去

      private void dispatchingValue(@Nullable ObserverWrapper initiator) {
            //正在处于分发状态中
            if (mDispatchingValue) {
                //分发无效
                mDispatchInvalidated = true;//1
                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;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    mDispatchingValue用于标记当前是否处于分发状态中,如果处于该状态,则在注释1处标记当前分发无效,直接return

    一路调用过来,ObserverWrapper是不为null的,ObserverWrapper为null无论是那种情况,都会调用considerNotify方法,代码如下所示

        private void considerNotify(ObserverWrapper observer) {
            if (!observer.mActive) {//1
                return;
            }
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);//2
                return;
            }
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            //noinspection unchecked
            observer.mObserver.onChanged((T) mData);//3
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    considerNotify方法中做了多次的判断

    • 注释1处,如果ObserverWrapper的mActive值不为true,就直接return
    • 注释2处,如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,并传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法回调

    如果判断条件都满足会调用Observer的onChanged方法,这个方法正是使用LiveData的observe方法的回调

    postValue/setValue 方法分析

    当调用MutableLiveData的observe方法后,还需要通过postValue/setValue方法来更新数据

    private final Runnable mPostValueRunnable = new Runnable() {
            @Override
            public void run() {
                Object newValue;
                synchronized (mDataLock) {
                    newValue = mPendingData;
                    mPendingData = NOT_SET;
                }
                //noinspection unchecked
                setValue((T) newValue);//1
            }
        };
        ...
        protected void postValue(T value) {
            boolean postTask;
            synchronized (mDataLock) {
                postTask = mPendingData == NOT_SET;
                mPendingData = value;
            }
            if (!postTask) {
                return;
            }
            ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2
        }
    
        @MainThread //3
        protected void setValue(T value) {
            assertMainThread("setValue");
            mVersion++;
            mData = value;
            dispatchingValue(null);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • postValue/setValue方法都定义在LiveData中

    根据注释1和注释2处,可以发现postValue方法实际上就是将setValue方法切换到主线程调用。注释3处说明setValue方法是运行在主线程中的,其内部调用了dispatchingValue方法

    ObserverWrapper为null的情况;从这里我们可以知道,无论是LiveData的observe方法还是LiveData的postValue/setValue方法都会调用dispatchingValue方法

    Transformations.map 方法分析

    除了以上讲的常用的方法之外,还可能会使用到Transformations.map和Transformations.switchMap方法,这里以Transformations.map为例;这个方法用来在LiveData对象分发给观察者之前对其中存储的值进行更改, 代码如下所示

    @MainThread
        public static <X, Y> LiveData<Y> map(
                @NonNull LiveData<X> source,
                @NonNull final Function<X, Y> mapFunction) {
            final MediatorLiveData<Y> result = new MediatorLiveData<>();//1
            result.addSource(source, new Observer<X>() {
                @Override
                public void onChanged(@Nullable X x) {
                    result.setValue(mapFunction.apply(x));
                }
            });
            return result;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Transformations.map方法运行在主线程,注释1处创建了MediatorLiveData,紧接着调用了它的addSource方法:

      */
        @MainThread
        public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
            Source<S> e = new Source<>(source, onChanged);//1
            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();//2
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    注释1处将传进来的LiveData和onChanged封装到Source类中,注释2处调用了Source的plug方法:

     private static class Source<V> implements Observer<V> {
            final LiveData<V> mLiveData;
            final Observer<? super V> mObserver;
            int mVersion = START_VERSION;
    
            Source(LiveData<V> liveData, final Observer<? super V> observer) {
                mLiveData = liveData;
                mObserver = observer;
            }
    
            void plug() {
                mLiveData.observeForever(this);//1
            }
    
            void unplug() {
                mLiveData.removeObserver(this);
            }
    
            @Override
            public void onChanged(@Nullable V v) {
                if (mVersion != mLiveData.getVersion()) {
                    mVersion = mLiveData.getVersion();
                    mObserver.onChanged(v);//2
                }
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注释2处可以看到Transformations.map方法传入的Observer的回调在这里进行处理

    注释1处,Source的plug方法会调用LiveData的observeForever方法

        @MainThread
        public void observeForever(@NonNull Observer<? super T> observer) {
            assertMainThread("observeForever");
            AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);//1
            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);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注释1处用AlwaysActiveObserver来对Observer进行包装,紧接着调用AlwaysActiveObserver的activeStateChanged方法**,其内部实际调用的是 ObserverWrapper 的 activeStateChanged 方法**

    来看 AlwaysActiveObserver 类是如何定义的

       private class AlwaysActiveObserver extends ObserverWrapper {
            AlwaysActiveObserver(Observer<? super T> observer) {
                super(observer);
            }
            @Override
            boolean shouldBeActive() {
                return true;
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    AlwaysActiveObserver 是 LiveData 的内部类,它继承自 ObserverWrapper,LiveData 内部类和 ObserverWrapper 的区别就是,它是永远处于Active状态的

    LiveData 关联类

    其中 MutableLiveData 继承自 LiveData, LifecycleOwner 和 Observer 和 LiveData 有关联的关系,ObserverWrapper 是 Observer 的包装类,因此它们有着关联的关系

    总结

    本文 全面介绍了 LiveData 的生命周期是如何变化的 希望大家在开发时尽量避免出现 因生命周期变化而出现的问题

    为了是大家能够更好的学习 Android Jetpack , 在这里特别提供一份 Android Jetpack 高级开发学习笔记, 里面包含了这些年学习 Android 开发所遇到的难题及其解决方案; 有需要这份 Android Jetpack 高级开发学习笔记 的朋友: 可以私信 发送 “笔记” 即可 免费获取; 希望大家阅读过后,能够 查漏补缺;早日成为高级开发者

    完整版 Android Jetpack 高级开发学习笔记获取方式:私信 发送 “笔记” 即可 免费获取

    对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

    技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

    加油!各位 Android 开发者们

  • 相关阅读:
    JSP页面中page指令有哪些属性及方法可使用呢?
    使用vue router的步骤是什么,并举个例子?
    如何让JOIN跑得更快?
    20240309web前端_第一周作业_完成电子汇款单
    LeetCode221109_122、27. 移除元素
    数字孪生管理系统,智慧校园建设规划方案
    ASP.NET Core 标识(Identity)框架系列(四):闲聊 JWT 的缺点,和一些解决思路
    一款构建Python命令行应用的开源库
    安卓与js交互
    医学影像坐标系问题(世界坐标系、解剖坐标系和图像坐标系)
  • 原文地址:https://blog.csdn.net/m0_62167422/article/details/126586581