JetPack-LiveData 原理分析

LiveData 是一个可以在给定生命周期内观察到的数据持有者类。 这意味着Observer可以与LifecycleOwner成对添加,并且仅当配对的 LifecycleOwner 处于活动状态时,才会通知此观察者有关包装数据的修改。

LifecycleOwner 被认为是活动的,如果它的状态是Lifecycle.State.STARTED或Lifecycle.State.RESUMED 。

通过observeForever(Observer)添加的observeForever(Observer)被视为始终处于活动状态,因此将始终收到有关修改的通知。 对于这些观察者,您应该手动调用removeObserver(Observer) 。

如果相应的 Lifecycle 移动到Lifecycle.State.DESTROYED状态,则会自动删除添加了 Lifecycle 的观察者。 这对于 Activity 和 Fragment 尤其有用,它们可以安全地观察 LiveData 而不必担心泄漏:它们在被销毁时会立即取消订阅。

此外,LiveData 有onActive()和onInactive()方法,可以在活动Observer的数量在 0 和 1 之间变化时得到通知。这允许 LiveData 在没有任何 Observer 正在积极观察时释放任何繁重的资源。
此类旨在保存ViewModel各个数据字段,但也可用于以解耦方式在应用程序中的不同模块之间共享数据。

类型参数:
– 此实例持有的数据类型

从调用处看起

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        //事件在主线程上调度
        assertMainThread("observe");
        //如果给定的所有者已经处于Lifecycle.State.DESTROYED状态,LiveData 会忽略调用
        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;
        }
        //为LifecycleBoundObserver绑定生命周期
        owner.getLifecycle().addObserver(wrapper);
    }

现在监听已经添加进去了,然后看看触发

触发的操作有 setValue 和 postValue两个方法

setValue只能在主线程里面操作;postValue可以在子线程里操作,它是借助Handler机制调用setValue进行实现的

@MainThread
    protected void setValue(T value) {
        // 主线程操作
        assertMainThread("setValue");
        mVersion++;
        //设置value值,供后面使用
        mData = value;
        dispatchingValue(null);
    }

dispatchingValue 这个方法在setValue的传入值为null,在另一个地方不为null。区别就是一个是直接触发设置的,另一个是根据生命周期的触发设置的。

    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;
    }

根据生命周期改变触发

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

void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            //如果在活跃状态就更新
            if (mActive) {
                dispatchingValue(this);
            }
        }

这个就是在恢复活跃状态时进行设置的

    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;
        }
        只有在setValue时才会增加,所以生命周期一直改变触发并不会多次调用onChange
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        // mVersion 
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

@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);
    }
    
    private class AlwaysActiveObserver extends ObserverWrapper {

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

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

observeForever 忽略了生命周期的控制,即使页面不可见 依然可以触发onChange, 但是要记得手动remove。防止内存泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值