LiveData浅析

LiveData是Jetpack中的重要一环,在MVVM架构中承担着核心的位置。
但我们暂时不去理会它在整个架构中的发挥,而是来关注其本质——LiveData本质是一个被观察者,即Observable。

概述

一个简单的Observable是这样的:

public class ConcreteObservable implements IObservable {
    
    
	Vector<IObserver> vector = new Vector();

	@Override
	public void attach(IObserver observer) {
    
    
		this.vector.addElement(observer);
	}

	@Override
	public void detach(IObserver observer) {
    
    
		this.vector.removeElement(observer);
	}

	@Override
	public void submit(String content) {
    
    
		Iterator var2 = this.vector.iterator();

		while(var2.hasNext()) {
    
    
			IObserver observer = (IObserver)var2.next();
			observer.update(content);
		}
	}
}

三个方法:添加观察者、移除观察者、通知观察者。

接下来我们就来看看LiveData的源码,来找出对应的方法。

添加观察者

首先是添加观察者:

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    
    //1
        assertMainThread("observe");//2
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
    
    //3
            // 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;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

很容易就找到。

  1. 先看参数,第二个参数不必说,第一个参数LifecycleOwner是一个能感知生命周期的接口,新版本(理论上是26.1.0之后,包括androidx)的Activity/Fragment均内部实现了此接口;
  2. 再看方法体,第一行在断言当前是主线程,意味着这个方法只能在主线程调用;
  3. 第二行判断当前组件的生命周期如果是DESTROYED也就是被销毁了的状态,那么便不生效;
  4. 接下来是把传入的observer进行了层层包裹,并添加至观察者集合,并由此判断是否存在重复添加的情况;
  5. 最后是生命周期的管理者同样添加了这个经过包装的observer;

移除观察者

接下来看看移除的逻辑:

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

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

同样是要判断是否在主线程,然后从观察者集合mObservers中移除,最后如果这个观察者不为空就会调用一次activeStateChanged方法;
activeStateChanged即观察者的触发。

通知观察者

上面对观察者的添加和移除都用到了ObserverWrapper,所以由这里切入,看一下ObserverWrapper

    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) {
    
    //1
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
    
    //2
                onInactive();
            }
            if (mActive) {
    
    //3
                dispatchingValue(this);
            }
        }
    }

可以看到其构造方法将最原始的观察者接口包装了一下:

public interface Observer<T> {
    
    
    void onChanged(T t);
}

然后来关注activeStateChanged方法,这个方法主要用于改变当前Observer的活跃状态
可以看到传入的值必须和当前的Observer的活跃状态不同,才能继续之后的逻辑;
接着判断如果当前的Observer处于活跃状态(mActive为true),就将当前LiveData的持有的Observer数量加1,否则就减1;
最后有3个判断:

  1. 如果现阶段未持有Observer且mActive为true,newActive为true且mActive为false,mActive会由false变为true的情况下,代表着此LiveData从无观察者的状态变为了有观察者的状态,则调用onActive方法,onActive是个空方法,隶属于LiveData,可覆写
  2. 所有Observer都被移除且mActive为false时,newActive为false且mActive为true,mActive会由true变为false的情况下,代表着此LiveData的最后一个观察者即当前的Observer也移除了,则调用onInactive方法,和onActive一样是个空方法
  3. mActive为true,当前的Observer处于激活状态,去触发通知操作

dispatchingValue方法即LiveData的通知方法,可以从LiveData的setValue方法看出:

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

同样是必须在主线程调用,并且每更新一次数据,会将当前LiveData的“版本”即mVersion累加更新一次,然后调用dispatchingValue;
说明dispatchingValue大概率是通知Observer的起始点;

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
    
    
        if (mDispatchingValue) {
    
    
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
    
    
            mDispatchInvalidated = false;
            if (initiator != null) {
    
    
                considerNotify(initiator);//1
                initiator = null;
            } else {
    
    
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
    
    
                    considerNotify(iterator.next().getValue());//2
                    if (mDispatchInvalidated) {
    
    
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

这里有mDispatchingValue和mDispatchInvalidated两个标记值,这两个标记值仅在这里出现,作用大致是为了防抖动;
然后会调用considerNotify方法,如果传入的Observer不为空,则直接通知此Observer,如果为空,则通知所有当前LiveData持有的Observer。
继续关注considerNotify方法:

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

依旧一步一步分析:

  1. 如果这个Observer处于不活跃状态,直接返回不作任何操作
  2. 如果Observer当前所处组件的生命周期在onStart之前,会调用activeStateChanged方法并传入true;由于第1步已经进行了判断,所以activeStateChanged方法中mActive一定是为true的,那么这个Observer的mActive状态会由true变为false,也就是这个Observer会变为不活跃状态并调用onInactive方法
  3. 一般情况下此条件是不成立的,mVersion会先行累加,Observer再复制mVersion这个值
  4. 如果以上的条件都不成立,那么就开始通知真正的观察者mObserver

至此,基本流程就已经走通了。
画一张简单的时序图就是这样的:
在这里插入图片描述

其他扩展

LifecycleBoundObserver

在添加观察者observe方法中,我们有看到LifecycleBoundObserver,就此看一下LifecycleBoundObserver

    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    
    
        @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(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
    
    
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
    
    
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
    
    
            return mOwner == owner;
        }

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

只看onStateChanged方法,这就是Observer这一方被通知后调用的逻辑,可以看到首先还是判断了生命周期的状态,如果已经销毁,那么就会调用removeObserver移除这个传入的Observer,否则就继续调用activeStateChanged;
先看activeStateChanged干了什么,这里传入了shouldBeActive()得出的布尔值,
这个布尔值代表着生命周期是否至少进行到了onStart的程度,即如果此Observer所处组件的生命周期尚在OnStart之前,那么传入的为false,否则为true;
那么这个onStateChanged方法又是哪里调用的呢?
其实,这个方法是LifecycleEventObserver接口提供的:

public interface LifecycleEventObserver extends LifecycleObserver {
    
    
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

在LiveData的observe方法中的最后一行

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    
    
		//...
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
		//...
        owner.getLifecycle().addObserver(wrapper);
    }

中,将其添加进了生命周期感知之中,其实现方法在LifecycleRegistry类中:

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
    
    
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
		//...
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
    
    
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            //...
        }
    }

可以看到这里把这个Observer又包装成另一种形态ObserverWithState 了:

    static class ObserverWithState {
    
    
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
    
    
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

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

顾名思义是带生命周期状态的Observer,并且dispatchEvent方法中会发生状态变化及触发操作,也就回调了LifecycleBoundObserver中的onStateChanged;
那么调用的dispatchEvent方法的时机又是什么时候呢?
和生命周期状态有关。

    public enum State {
    
    
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
    }

当第一次添加此Observer的时候,这个Observer状态被赋为INITIALIZED,后面会有一个比较判断:

statefulObserver.mState.compareTo(targetState) < 0

这个targetState可以理解为Observer所在组件的生命周期状态,只要这个被包装过的Observer的生命周期状态在targetState之前,那么就调用一次dispatchEvent。
而首次添加Observer的时候,这个生命周期是为INITIALIZED的,在一般情况,我们至少会在组件onCreate或之后再添加Observer,就是这个targetState至少是CREATED之后,因此INITIALIZED<CREATED是成立的;

        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;

所以理论上Observer在被首次添加时就会触发一次
这也就是LiveData与传统观察者模式最大的不同点,它与生命周期是高度绑定的。

postValue

除了只能在主线程运行的setValue方法以外,LiveData也提供了没有限制的postValue方法:

    static final Object NOT_SET = new Object();
    volatile Object mPendingData = NOT_SET;
    final Object mDataLock = new Object();

    protected void postValue(T value) {
    
    
        boolean postTask;
        synchronized (mDataLock) {
    
    
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
    
    
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    
    private final Runnable mPostValueRunnable = new Runnable() {
    
    
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
    
    
            Object newValue;
            synchronized (mDataLock) {
    
    
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

很容易就看出来,postValue方法最终还是会调用setValue方法,但中间使用ArchTaskExecutor将其切换到了主线程;

public class ArchTaskExecutor extends TaskExecutor {
    
    
    @NonNull
    private TaskExecutor mDelegate;

    @NonNull
    private TaskExecutor mDefaultTaskExecutor;
    
    private ArchTaskExecutor() {
    
    
        mDefaultTaskExecutor = new DefaultTaskExecutor();
        mDelegate = mDefaultTaskExecutor;
    }

    @Override
    public void executeOnDiskIO(Runnable runnable) {
    
    
        mDelegate.executeOnDiskIO(runnable);
    }

    @Override
    public void postToMainThread(Runnable runnable) {
    
    
        mDelegate.postToMainThread(runnable);
    }
}

ArchTaskExecutor的postToMainThread其实又是使用的DefaultTaskExecutor,

public class DefaultTaskExecutor extends TaskExecutor{
    
    
	    @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来执行。

observeForever

我们在之前看到的是observe方法,只能添加与生命周期相关的Observer,而LiveData也另外提供了一个添加与生命周期无关的Observer的方法:

    @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包装类名就明白了,这个是一个“永远处于活跃状态”的Observer,摆脱了生命周期的影响:

    private class AlwaysActiveObserver extends ObserverWrapper {
    
    

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

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

这样就和传统的观察者模式又一样了,算是一种兼容。

猜你喜欢

转载自blog.csdn.net/ifmylove2011/article/details/116520010