Android JetPack学习笔记-LiveData

本文详细介绍了 Android 中 LiveData 的使用,包括 postValue 和 setValue 的区别,它们如何切换线程,以及 LiveData 如何与 Lifecycle 进行绑定。同时,文章剖析了 LiveData 的 observer 方法,响应机制,以及 observeForever 的特点。最后,解释了 dispatchingValue 方法的判断逻辑,展示了 setValue 的源码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.使用

1.1 postValue和setValue的区别以及怎么切换的线程

2.observer方法

3.响应 

4.ObserverForerver()         

5.duspatchingValue方法的判断

6.setValue


1.使用

        var liveData = MutableLiveData<String>()
        liveData.observe(this) {
            Log.e("TAG", "lifecycleInit: $it")
        }
        liveData.setValue("2")

        这三行代码不复杂,第一行进行实例化一个livedata对象,第二行进行绑定联系。最后一行设置数据。 其中setValue在主线程使用,postValue在子线程使用。我们先浅看一下postValue和setValue的区别。setValue咱们先看postValue,setValue后续看。

1.1 postValue和setValue的区别以及怎么切换的线程

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

        咱们看到这个方法的最后一行,能看到切换到主线程,然后传了一个Runnable。我们来看看这个Runnable里有啥

    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

        这样就很显然了,切换到主线程之后,调用了setValue。这里切换线程使用的也是Handler来切换线程的。我就直接跳到关键步骤了。

    @Override
    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = createAsync(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

        最终是调用到了DefaultTaskExecutor方法中的此方法,可以看出使用了Handler进行的线程切换。

2.observer方法

        LiveData是如何进行绑定的呢?在我们想来他跟Activity/Fragment进行了生命周期的绑定,然后数据变化时咱们又可以监听到。这其实是如何做到的,这又是观察者又是被观察者的情况。让我们来看看它的observer方法()

    @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);
        .......
        owner.getLifecycle().addObserver(wrapper);
    }

        咱们看这个方法,显示判断了执行的线程,然后判断被观察者(Activity/Fragment)的状态,如果是销毁的就没必要建立关联了。我们看到最后一行被观察者与wrapper建立关联,就猜出wrapper应该是观察者。我们来看看LifecycleBoundObserver

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

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

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

        这样咱们就知道,livedata是怎么和被观察者(Aactivity/Fragment)的生命周期进行绑定了,有了之前Liftcycle的基础。

3.响应 

        那接下来是如何进行响应的呢?既然跟其被观察者的生命周期建立了关系,咱们或许应该去之前Lifecycle中的代码中寻找,想想是ReportFragment中进行了相关调用。Lifecycle咱们已经说过了,直接跳到相关代码中。

observer.dispatchEvent(lifecycleOwner, event);

        这在LifecycleRegistry类中的forwardPassbackwardPass方法中有调用到。咱们点击dispatchEvent中看详情。

        void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = event.getTargetState();
            mState = min(mState, newState);
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }

        这边调用了LifecycleEventObserver类中的onStateChanged,咱们刚才在绑定联系的时候,使用的是LifecycleBoundObserver类,它实现了LifecycleEventObserver,我们进入查看该方法的实现。

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

        引入眼帘的就是判断被观察者的状态是否为销毁DESTORYED),如果被销毁则移除并退出。然后调用shouldBeActiveactiveStateChanged方法。我们先来看shouldBeActive

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

        其进行被观察者的状态判断,判断其是否显示。STARTED,RESUME为显示。

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

        其中调用了changeActiveCounter方法,然后如果是显示的状态就执行dispatchingValue。先来看看changeActiveCounter方法。

    @MainThread
    void changeActiveCounter(int change) {
        ......
        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;
        }
    }

        显示时调用onActive方法,没显示调用onInactive方法。这两个方法liveData没有实现,是留给咱们可以自己处理自己想要的逻辑。

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

        这里边标记的变化,后续讲。先看其调用了considerNotify方法。

    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        ......
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

        这个方法再次进行了判断是否显示,然后再进行了版本的判断,判断其是否为最新的版本。最后版本更新,调用咱们的观察者的onChanged方法。

4.ObserverForerver()         

        这是liveData提供的另一个订阅,从单词上我们可以知道是永远订阅。我们来看源码。

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

        我们发现这里使用的是AlwaysActiveObserver类,再来我们没有看到生命周期的绑定,其实这个也能理解,永远订阅那咱们绑定生命周期没有任何意义。我们来看看,AlwaysActiveObserver的实现。

    private class AlwaysActiveObserver extends ObserverWrapper {

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

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

        它的sholdBeActive永远返回true,也就是永远是显示的。这也对Forever的单词有对应。值得注意的是这样的订阅,咱们最好在用完的时候,进行remove掉。

5.duspatchingValue方法的判断

        我们先来看代码示例:

        liveData = MutableLiveData<String>()
        liveData.observe(this) {
            Log.e("TAG", "lifecycleInit1: $it")
            if (it.equals("1")) {
                liveData.value = "2"
            }
        }
        liveData.observe(this) {
            Log.e("TAG", "lifecycleInit2: $it")
        }
        test_click.setOnClickListener(){
            liveData.value = "1"
        }

        可以先猜猜,打印会是什么?1122?

         结果是122!第二个observer的1没有显示。咱们来看看dispatchingValue的代码。

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

        重要的标记值mDispatchingValuemDispatchInvalidated mDispatchingValue可以理解为防止递归,2一进来就直接被return掉了。mDispatchInvalidated可以字面理解分发是否失效。虽然2一进来就return掉了,但是它走之前把是否失效的标记改为了true。所以递归的return掉之后,第1个1走到if的判断后会直接break。之后再走到while的判断,此时是否失效为true,会重新走到循环里,此时for循环里面2个observer的value因为上次setValue("2")的关系,他们的value全是2了。于是打印了2个2。

6.setValue

        其实这个没啥好讲了,咱们上头都讲了。直接上源码:

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

        其中做了主线程校验、版本增加、value赋值和执行disPatchingValue方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值