LiveData源码解析

作者: 小乌贼007 | 来源:发表于2019-11-20 21:56 被阅读0次

    LiveData官方资料
    Lifecycle官方资料
    ViewModel官方资料

    本文适合对Lifecycle、LiveData和ViewModel的使用场景和用法有一定了解并想进一步探索LiveData实现方式的开发者。如果不是很了解,请先参考上述三篇官方文档。
    在ACC架构出现之前,我们更新UI的方式大多有两种:

    • onResume回调中获取数据刷新ui,缺点是数据可能没变化也去刷新造成资源浪费。
    • 设置监听,当数据发生变化时通过回调更新ui,缺点是应用在后台也更新了UI,若用户不再回来,则更新没有意义,且设置监听需要维护listener,代码较多且易发生内存泄漏。

    另一大痛点是当某个数据可以被多个地方改动且又有多个地方对该数据感兴趣时,对数据一致性的维护需要花费些精力,例如用户的登录状态的维护(多个地方可以登录/退出登录,多个地方依赖用户登录信息)。目前可使用的方案有EventBus。

    ACC框架的出现解决了上述问题,LiveData和Lifecycle是ACC框架实现数据驱动UI的关键类,建立起View对LiveData的观察之后,我们不用再关心数据变化带来的ui更新问题,且LiveData对View的更新是高效的。LiveData是个观察者,同时也是被观察者,它需要观察LifecycleOwner(Activity/Fragment)的生命周期,同时被对数据变化感兴趣的View观察。当数据发生变化且界面在前台时,LiveData会主动更新UI,当界面从后台回到前台时若发现数据变化了,UI也会得到更新。

    下面来看LiveData的一个使用Demo,一般LiveData会和ViewModel一起使用,这边为了简单,没有使用ViewModel:

    public class StockLiveData extends LiveData<BigDecimal> {
        private static StockLiveData sInstance;
        private StockManager stockManager;
    
        private SimplePriceListener listener = new SimplePriceListener() {
            @Override
            public void onPriceChanged(BigDecimal price) {
                //当股价发生变化时,更新livedata,ui会自动更新
                setValue(price);
            }
        };
    
        @MainThread
        public static StockLiveData get(String symbol) {
            if (sInstance == null) {
                sInstance = new StockLiveData(symbol);
            }
            return sInstance;
        }
        //单例
        private StockLiveData(String symbol) {
            stockManager = new StockManager(symbol);
        }
    
        @Override
        protected void onActive() {
            //当有界面回到前台时,监听股票价格
            stockManager.requestPriceUpdates(listener);
        }
    
        @Override
        protected void onInactive() {
            //当没有界面在前台时,不监听股票价格
            stockManager.removeUpdates(listener);
        }
    }
    
    public class MyFragment extends Fragment {
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            Observer<String> priceObserver = new Observer<String>() {
                   @Override
                   public void onChanged(String s) {
                           //股票价格变动,会更新ui
                   }
            };
            StockLiveData.get(symbol).observe(this,  priceObserver);
        }
    }
    

    下面来分析源码。
    名词解释:

    • LifecycleOwner 指的拥有生命周期的类,如Activity、Fragment。

    • Active:指的是LifecycleOwner的状态处在STARTED 或者 RESUMED,即界面可见。

    • Observer:指的是观察LiveData的对象,如demo中的priceObserver。

    • Observer的Active状态和LifecycleOwner的Active状态一致,即当界面处在Active状态时才将数据变化通知观察者。Active Observer指的是Observer 所在的LifecycleOwner处在Active状态的Observer。

    • Observer得到通知有两个时机,

      • 时机1: LiveData值的改变会通知所有active Observer。
      • 时机2: Observer状态(也是LifecycleOwner的状态)由InActive状态变为Active状态时,会通知该观察者。
    • LiveData Active状态:当LiveData的所有Observer都处在InActive状态时,LiveData是InActive状态,否则LiveData是Active状态。LiveData由InActive状态变为Active状态时会回调onActive方法;LiveData由Active状态变为InActive状态时会回调onInactive方法。

    public abstract class LiveData<T> {
        //LiveData的值保存在mData中
        private volatile Object mData = NOT_SET;
    
        //同步锁对象,用于postValue方法,该方法用于在worker thread更新livedata的值,多个线程操作mData,需要加锁。
        private final Object mDataLock = new Object();
        //mData初始版本号
        static final int START_VERSION = -1;
        //mData初始值
        private static final Object NOT_SET = new Object();
        //保存观察者的map
        private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
                new SafeIterableMap<>();
    
        //界面处在active状态的观察者的数量,用于回调onActive和onInactive方法。
        private int mActiveCount = 0;
    
        //mPendingData保存postValue方法的参数
        private volatile Object mPendingData = NOT_SET;
        //mData版本号,mData每次改变版本号要+1
        private int mVersion = START_VERSION;
    
        private boolean mDispatchingValue;
        @SuppressWarnings("FieldCanBeLocal")
        private boolean mDispatchInvalidated;
    
    
        //改变mData的值,通知观察者,只能在主线程执行该方法。
       @MainThread
        protected void setValue(T value) {
            assertMainThread("setValue");
            //版本号+1
            mVersion++;
            mData = value;
           //通知所有观察者 时机1
            dispatchingValue(null);
        }
    
        private static void assertMainThread(String methodName) {
            if (!ArchTaskExecutor.getInstance().isMainThread()) {
                throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                        + " thread");
            }
        }
    
        //通知观察者,若initiator为空,则通知所有观察者,若initiator不为空,则仅通知该initiator
        private void dispatchingValue(@Nullable ObserverWrapper initiator) {
            //mDispatchingValue和mDispatchInvalidated两个标记量是为了防止死循环,这里有递归调用。
            if (mDispatchingValue) {
                mDispatchInvalidated = true;
                return;
            }
            mDispatchingValue = true;
            do {
                mDispatchInvalidated = false;
                if (initiator != null) {
                    //通知initiator
                    considerNotify(initiator);
                    initiator = null;
                } else {
                     //遍历map通知所有观察者
                    for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                        considerNotify(iterator.next().getValue());
                        if (mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while (mDispatchInvalidated);
            mDispatchingValue = false;
        }
    
        //若observer处在active状态则通知,否则不通知。
        private void considerNotify(ObserverWrapper observer) {
            //观察者处在非active状态,不通知。
            if (!observer.mActive) {
                return;
            }
            //这里observer.mActive=true,LifecycleOwner可能状态已经发生变化,但是没及时通知observer,重新探测一下观察者状态
            if (!observer.shouldBeActive()) {
                //观察者状态由Active变为非Active,改变观察者状态(主动探测得到的状态改变),观察者状态的改变也会通知观察者。
                observer.activeStateChanged(false);
                return;
            }  
            //观察者的数据更新,则返回,理论上不会走到这里吧?(我的理由是所有操作都在主线程)
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            //数据发生变化且观察者处在active状态,通知观察者。
            //noinspection unchecked
            observer.mObserver.onChanged((T) mData);
        }
    
       //设置livedata的观察者和被观察者。
        @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);
            //若观察者没加过,着将观察者加入观察者map。
            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;
            }
            //当LifecycleOwner的状态发生变化,需要通知观察者。
            owner.getLifecycle().addObserver(wrapper);
        }
    
        //连接LifecycleOwner和Observer,将Observer状态连接到LifecycleOwner
        class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
            @NonNull final LifecycleOwner mOwner;
    
            LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
                super(observer);
                mOwner = owner;
            }
    
            //获取LifecycleOwner最新的Active状态
            @Override
            boolean shouldBeActive() {
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
            //当LifecycleOwner的生命周期发生变化时会回调该方法。
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                //当观察者所在的LifecycleOwner被销毁,删除掉观察者。
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    removeObserver(mObserver);
                    return;
                }
                //观察者Active状态变化,可能要通知观察者。
                activeStateChanged(shouldBeActive());
            }
    
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
    
            @Override
            void detachObserver() {
                mOwner.getLifecycle().removeObserver(this);
            }
        }
    
        //Observer 的包装类,增加Observer观察数据的版本信息,
       //增加Observer的Active状态信息,当状态发生变化时,可能通知该Observer。
        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;
                //wasInactive表示LiveData原状态。
                boolean wasInactive = LiveData.this.mActiveCount == 0;
                LiveData.this.mActiveCount += mActive ? 1 : -1;
                //LiveData由InActive到Active回调onActive
                if (wasInactive && mActive) {
                    onActive();
                }
                 //LiveData由Active到InActive回调onInactive
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
                //观察者由InActive状态转为Active状态,通知该观察者可能发生数据变化。
                if (mActive) {
                    dispatchingValue(this);
                }
            }
        }
    
        //在worker 线程更新mData
        protected void postValue(T value) {
            boolean postTask;
            //同步锁
            synchronized (mDataLock) {
                //若mPendingData有值了,说明已经有worker thread将value赋值给mPendingData,但主线程还未将mPendingData赋值给mData,
               //此时直接将value复制给mPendingData即可,当主线程执行时,会将更新后的mPendingData值复制给mData。
                postTask = mPendingData == NOT_SET;
                mPendingData = value;
            }
            if (!postTask) {
                return;
            }
            //将更新任务交给主线程。
            ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
        }
    
        //在主线程将mData的值更新为mPendingData,postValue方法会更新mPendingData的值,结合postValue方法分析。
        private final Runnable mPostValueRunnable = new Runnable() {
            @Override
            public void run() {
                Object newValue;
                synchronized (mDataLock) {
                    newValue = mPendingData;
                    mPendingData = NOT_SET;
                }
                //noinspection unchecked
                setValue((T) newValue);
            }
        };
    
        //当mData的值发生变化时即通知observer,不管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 != null && existing instanceof LiveData.LifecycleBoundObserver) {
                throw new IllegalArgumentException("Cannot add the same observer"
                        + " with different lifecycles");
            }
            if (existing != null) {
                return;
            }
            wrapper.activeStateChanged(true);
        }
    
        //删除观察者
        @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);
        }
    
        //删除某个界面的所有观察者
        public void removeObservers(@NonNull final LifecycleOwner owner) {
            assertMainThread("removeObservers");
            for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
                if (entry.getValue().isAttachedTo(owner)) {
                    removeObserver(entry.getKey());
                }
            }
        }
        //获取LiveData的值
        public T getValue() {
            Object data = mData;
            if (data != NOT_SET) {
                //noinspection unchecked
                return (T) data;
            }
            return null;
        }
    
        //获取LiveData值的版本
        int getVersion() {
            return mVersion;
        }
    
        //LiveData状态回调
        protected void onActive() {
    
        }
    
       //LiveData状态回调
        protected void onInactive() {
    
        }
    
        @SuppressWarnings("WeakerAccess")
        public boolean hasObservers() {
            return mObservers.size() > 0;
        }
    
        @SuppressWarnings("WeakerAccess")
        public boolean hasActiveObservers() {
            return mActiveCount > 0;
        }
    
        private class AlwaysActiveObserver extends ObserverWrapper {
    
            AlwaysActiveObserver(Observer<? super T> observer) {
                super(observer);
            }
    
            @Override
            boolean shouldBeActive() {
                return true;
            }
        }
    
    }
    

    相关文章

      网友评论

        本文标题:LiveData源码解析

        本文链接:https://www.haomeiwen.com/subject/zfqaictx.html