Android源码解析:LiveData

作者: 小村医 | 来源:发表于2018-12-17 18:33 被阅读2次

    概述

    简单地来说,LiveData就是一个持有数据的类。

    LiveData中的数据可以被观察者订阅,当数据被修改时通知观察者。观察者包括Fragment、Activity以及Service等。
    LiveData能够感知观察者的生命周期。只有在观察者处于激活状态(STARTED之后的状态)才会收到数据更新;并在onDestroy时自动解注册观察者,避免崩溃,且减少内存泄露。

    使用

    使用LiveData子类MutableLiveData,维护一个String类型的数据:

    public class MyViewModel extends ViewModel{
        private MutableLiveData<String> mData;
        public MutableLiveData<String> getData() {
            if (mData == null) {
                mData = new MutableLiveData<>();
            }
            return mData;
        }
        public void setData(String data){
            //更新livedata中的值
            mData.setValue(data);
        }
    }
    

    接着注册观察者:

    
    public class LiveDataFragment extends Activity{
        private MyViewModel mViewModel;
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
            mViewModel.getData().observe(this, new Observer<String>() {
                @Override
                public void onChanged(@Nullable String data) {
                    //LiveData数据变化后的回调
                }
            });
        }
    }
    

    主要类

    LiveData类图.png

    源码分析

    从以下几个方面对源码进行分析:

    1. 如何注册观察者

         public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            assertMainThread("observe");
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {
                // 当前Activity/Fragment为destory状态时忽略
                return;
            }
            LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
            //mObservers(一个类似Map的容器)的putIfAbsent()方法用于判断容器中的observer是否有已经和wrapper关联,
            //如果已关联则返回关联值,否则关联之后并返回wrapper
            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;
            }
           //使用上面new的wrapper对象监听Activity/Fragment的生命周期
            owner.getLifecycle().addObserver(wrapper);
        }
    

    LifecycleBoundObserver继承自ObserverWrapper对象并实现GenericLifecycleObserver接口,当组件的生命周期发生变化后会通过onStateChanged()方法回调过来通知ObserverWrapper生命周期变化

    2. 如何监听Activity/Fragment的生命周期

    通过上面的分析,可以知道组件生命周期的观察者就是LifecycleBoundObserver对象,下面我们看一下LifecycleBoundObserver具体实现:

        class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
            @NonNull
            final LifecycleOwner mOwner;
    
            LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
                super(observer);
                mOwner = owner;
            }
    
            @Override
            boolean shouldBeActive() {
                // 判断组件是否active
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    //组件destory后移除监听者
                    removeObserver(mObserver);
                    return;
                }
                activeStateChanged(shouldBeActive());
            }
    
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
    
            @Override
            void detachObserver() {
                mOwner.getLifecycle().removeObserver(this);
            }
        }
    

    当组件生命周期发生变化时,onStateChanged()方法会被调用。如果当前处于Lifecycle.State.DESTROYED时,会自动将观察者移除;若当前处于ACTIVE状态,则继续执行,调用activeStateChanged方法,该方法在ObserverWrapper中实现

            void activeStateChanged(boolean newActive) {
                if (newActive == mActive) {
                    return;
                }
                //设置当前监听的组件是否active,只有处于active状态的组件才会通过观察者模式通知组件数据变化
                mActive = newActive;
                boolean wasInactive = LiveData.this.mActiveCount == 0;
                LiveData.this.mActiveCount += mActive ? 1 : -1;
                if (wasInactive && mActive) {
                    onActive();
                }
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
                if (mActive) {
                    dispatchingValue(this);
                }
            }
    

    最后调用的是dispatchingValue()进行数据变化时的消息通知

        void dispatchingValue(@Nullable ObserverWrapper initiator) {
            if (mDispatchingValue) {
                mDispatchInvalidated = true;
                return;
            }
            mDispatchingValue = true;
            do {
                mDispatchInvalidated = false;
                //组件生命周期变化时initiator不为空,considerNotify直接调用Observer的onChanged方法
                if (initiator != null) {
                    considerNotify(initiator);
                    initiator = null;
                } else {
                    //遍历所有观察者调用onChanged通知数据变化
                    for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                        considerNotify(iterator.next().getValue());
                        if (mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while (mDispatchInvalidated);
            mDispatchingValue = false;
        }
    

    3. setValue()或postValue()方法后,通知观察者更新数据

    LiveData提供了两种改变数据的方法:在主线程调用的setValue()方法,以及在子线程中调用的postValue()方法。现在看下两个方法的具体实现:

        protected void setValue(T value) {
            assertMainThread("setValue");
            mVersion++;
            mData = value;
            dispatchingValue(null);
        }
        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() {
            @Override
            public void run() {
                Object newValue;
                synchronized (mDataLock) {
                    newValue = mPendingData;
                    mPendingData = NOT_SET;
                }
                //最终通过Handler在主线程调用setValue
                setValue((T) newValue);
            }
        };
    public void postToMainThread(Runnable runnable) {
            if (mMainHandler == null) {
                synchronized (mLock) {
                    if (mMainHandler == null) {
                        mMainHandler = new Handler(Looper.getMainLooper());
                    }
                }
            }
            //noinspection ConstantConditions
            mMainHandler.post(runnable);
        }
    

    相关文章

      网友评论

        本文标题:Android源码解析:LiveData

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