Android LiveData笔记

LiveData特性:

    1、只有在活跃状态(STARTED,RESUMED)才会收到通知,非活跃状态不会收到更新通知。

    2、只有在数据发生变化时才发生更新,且只发送给处于活跃状态的观察者。

    3、观察者在首次从非活跃状态变为活跃状态时,会收到更新通知。若第二次从非活跃状态转为活跃状态,则只在值变化时,才会收到通知。

使用注意:

    1、尽量放在ViewModel中,不放在Activity或Fragment中,原因:其一、避免Activity/Fragment冗余;其二、在Activity/Fragment配置更改后继续存在。

    2、onCreate方法是开始观察LiveData对象的正确着手点。(onCreate方法调用时,Activity/Fragment正处于INITIALIZED状态)

LiveData类图:

Android LiveData笔记

    从图中可以看出LiveData以一个Map来保存Observer,并且用ObserverWrapper对Observer进行了封装。封装的目的是为了获取“组件状态”,只通知处于活跃状态的观察者。

    接下来,以一个介绍LiveData运作过程。包含:一、添加观察者;二、数据发生变化,给观察者发送更新通知;三、生命周期状态发生变化,发送更新通知;四、生命周期结束,撤销观察者。

    LiveData执行过程:

    通常可能的LiveData用法如下:

searchPageViewModel.hintWordDataList.observe(viewLifecycleOwner, Observer {
            adapter.dataList = it
            adapter.notifyDataSetChanged()
        })

一、添加观察者:

    上面的observe方法的实现如下:

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // 如果Activity或Fragment处于DESTROYED状态,就不需要设置观察者了
            return;
        }
        //封装Observer和LifecycleOwner到wrapper中,以实现只通知活跃状态的Observer的目的
        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);
    }

    在添加LiveData的观察者时,首先将LifecycleOwner和Observer封装到了LifecycleBoundObserver中,此类的作用是:一、提供Observer的状态(即生命感知组件的状态),以实现只通知活跃状态Observer的目的。二、实现了LifecycleEventObserver接口,以观察生命感知组件(Activity或Fragment)的状态变化,在生命感知组件变为活跃状态时,给LiveData的观察者发送一个更新通知。然后,将LifecycleBoundObserver作为“value”,添加到了一个以Observer为“key”的Map中。

二、数据发生变化,给观察者发送更新通知

    通常,LiveData会调用setValue方法更新值,其代码如下:

    protected void setValue(T value) {
        assertMainThread("setValue");
        //mVersion表示“值”的版本,每更新一次就加1
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

    接下来,会调用dispatchingValue方法,以通知观察者值发生变化,注意这里的参数值为null,此方法代码如下:

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            //正在通知观察者,则直接返回,不重复执行相同的操作
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                //通知指定观察者initiator,LiveData的值发生变化
                considerNotify(initiator);
                initiator = null;
            } else {
                //通知所有观察者,LiveData的值发生变化
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

    此方法的形参为initiator,若initiator不为null,则只对initiator指定的观察者发送更新通知;若为null,则对所有注册的观察者都发送更新通知。在此会调用considerNotify发送更新通知,此方法代码如下:

    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // 检查是否处于活跃状态(STARTED或RESUMED)
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        // 检查是否处理过LiveData的最新值
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        // 未处理过LiveData的最新值,进行处理:
        // 更新mLastVersion并调用Observer的onChanged方法
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

三、生命周期状态发生变化,发送更新通知

    前面提过的LifecycleBoundObserver会实现LifecycleEventObserver接口,以观察生命感知组件的状态。此类代码如下:

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

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

        //检查Lifecycle(Activity/Fragment)是否处于活跃状态
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            //获取Lifecycle的状态
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                //通知观察者Observer 状态发生变化
                // 若状态为STARTED或RESUMED,则shouldBeActive()为true
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

        ......
    }

    在生命感知组件的状态变化时,会调用onStateChanged方法,在此方法中,会检查是否处于活跃状态,若处于活跃状态,会调用activeStateChanged通知观察者Observer,状态发生变化,此方法代码如下:

        void activeStateChanged(boolean newActive) {
            //若处于活跃状态,newActive为true
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;

            // 告知LiveData,使mActiveCount值加1或减1
            // mActiveCount表示处于活跃状态的观察者的数量
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                //给当前观察者发送更新通知
                //观察者不一定会更新,由观察者的mLastVersion与LiveData的mVersion决定
                dispatchingValue(this);
            }
        }

四、生命周期结束,撤销观察者

    当Activity/Fragment处于DESTROYED状态时,LifecycleBoundObserver会收到通知,并撤销LiveData的观察者,代码如下:

public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            //获取Lifecycle的状态
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                //撤销LiveData的观察者
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                //通知观察者Observer 状态发生变化
                // 若状态为STARTED或RESUMED,则shouldBeActive()为true
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

    此方法会调用removeObserver方法,代码如下:

public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        //从LiveData的Map中移除观察者
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        //最后一次通知观察者,其被移除
        removed.detachObserver();
        removed.activeStateChanged(false);
    }

    在此方法中,会调用detachObserver方法告知观察者,其被移除,以使观察者做一些移除后的操作,代码如下:

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

    这里,在观察者被移除之后,也就不需要观察生命感知组件(Activity或Fragment)的状态变化了,所以要移除之前对生命感知组件添加的观察者。

    至此,LiveData的执行过程就分析结束了。

上一篇:观察者模式


下一篇:行为设计模式