• LiveData源码赏析 —— 基本使用


    作者:晚来天欲雪_
    转载地址:https://juejin.cn/post/7112991690914267143

    LiveData是一个抽象类,我们一般使用MutableLiveData创建LiveData对象。

    public class MutableLiveData<T> extends LiveData<T> {}
    
    • 1

    MutableLiveData仅仅继承了LiveData,没有做其他额外的操作。

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1.首先assertMainThread()方法会先判断当前调用线程,如果不在主线程则会抛出异常
    2.然后通过owner获取Lifecycle当前所处于的状态,如果已经销毁(DESTROYED),则此时注册观察者毫无意义,直接忽略。
    3.将owner和observer包装成LifecycleBoundObserver对象。
    4.将observer作为key,wrapper作为value存储在mObservers,如果mObservers之前不存在observer,putIfAbsent()方法直接添加并返回null,如果已经存在,则依旧为原来的值,并返回旧的值。
    5.如果LiveData内部之前已经持有了observer对象并且绑定了其他LifecycleOwner对象,则抛出异常。
    6.如果已经持有observer对象但是绑定的是同一个LifecycleOwner对象则忽略此次注册。
    7.将wrapper添加到Lifecycle。

    observe()方法中将owner和observer包装成LifecycleBoundObserver对象,LifecycleBoundObserver不仅继承了ObserverWrapper抽象类,还实现了
    LifecycleEventObserver接口,而LifecycleEventObserver实际继承于LifecycleObserver接口。

    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    	//......省略部分代码
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
        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

    LifecycleBoundObserver需要LifecycleOwner处于活跃状态,生命周期至少是STARTED状态,而且它是与生命周期绑定的,所以detachObserver()方法中需要将自己移除,当生命周期变化的时候会回调onStateChanged()方法,如果Lifecycle已经处于DESTROYED状态了,则主动移除mObserver,否则根据当前状态分发数据。

    observeForever

    observeForever()方法可以注册一个没有关联LifecycleOwner对象的Observer。在这种情况下Observer被认为始终处于活动状态,因此当有数据变化时总是会被通知。LiveData不会主动移除这些Observer,需要我们在合适的机会主动调用removeObserver()方法进行移除。

    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (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
    1. observeForever()方法和observe()方法一样都必须在主线程调用。
    2. 将observer包装成AlwaysActiveObserver对象。
    3. 如果LiveData内部之前已经持有了observer对象并且关联在LifecycleBoundObserver上面,则会抛出异常。
    4. 调用activeStateChanged()方法,因为当前 LiveData 可能已经被设置值了。
    AlwaysActiveObserver也是ObserverWrapper的子类。
     private class AlwaysActiveObserver extends ObserverWrapper {
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }
        boolean shouldBeActive() {
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    与LifecycleBoundObserver不同的是shouldBeActive()方法固定返回true,表明它一直是活跃状态。只要有数据变化都会进行回调,所以为了避免内存泄漏和空指针异常,我们应该在不需要Observer的时候将它移除。

    removeObserver

    @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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 从map中移除Observer。
    2. 调用被移除的Observer的detachObserver方法并且把状态mActive置为false。

    ObserverWrapper

    前面提到的LifecycleBoundObserver和AlwaysActiveObserver都是ObserverWrapper的子类。

    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;
    	//省略部分代码.....
        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ObserverWrapper对Observer做了一层包装,加入了活跃状态和版本信息,当活跃状态改变的时候会调用activeStateChanged()方法,他会统计Observer活跃数并且在Observer活跃的时候分发数据。

    changeActiveCounter

    @MainThread
    void changeActiveCounter(int change) {
        int previousActiveCount = mActiveCount;
        mActiveCount += change;
        if (mChangingActiveState) {
            return;
        }
        mChangingActiveState = true;
        try {
            while (previousActiveCount != mActiveCount) {
                boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
                boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
                previousActiveCount = mActiveCount;
                if (needToCallActive) {
                    onActive();
                } else if (needToCallInactive) {
                    onInactive();
                }
            }
        } finally {
            mChangingActiveState = false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    changeActiveCounter()方法改变当前激活状态的observe数量,然后判断如果激活状态得数量由从0到1调用了onActive方法,激活状态数量由1到0调用了onInactive方法。这两个方法都是空实现,需要LiveData的子类按需要实现。加while是为了防止在执行过程中changeActiveCounter()方法被调用,导致mActiveCount被更新。

  • 相关阅读:
    环境编程代码实例:“加/卸载” Zend Framework 2
    Tomcat是如何打破“双亲委派“机制的
    LINUX网络FTP服务
    g++ 重要编译参数
    基本介绍——数据挖掘
    RPC中实现提供者信息变化后通知消费者
    Java类成员和函数的执行顺序(static、非static、代码块、构造函数)
    MySQL---触发器详解
    解决edge浏览器无法打开pdf文件问题
    1.4_14 Axure RP 9 for mac 高保真原型图 - 案例13 【动态面板-滚动条3】双向同步滚动
  • 原文地址:https://blog.csdn.net/weixin_61845324/article/details/125504741