Android Jetpack架构组件(五)LiveData原理篇

前言
上一篇我们讲解了Jetpack中LiveData使用篇, 本片我们从源码角度来分析LiveData.是如何实现的。

本篇目录如下:

  • LiveData源码分析
  • LiveData.setValue/postValue源码分析
  • Transformations.map()的源码分析

LiveData源码分析

  • 我们先以上一篇的基本使用入手来分析源码
    class TestActivity : AppCompatActivity() {
    
        private val TAG by lazy {
            TestActivity::class.java.simpleName
        }
    
        private val data = MutableLiveData<String>()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            //-----1-----
            data.observe(this, Observer {
                Log.i(TAG, "value:  $it ")
            })
        }
    
        fun onTest(view: View) {
            //-----2-----
            data.postValue("LiveData")
        }
        //打印信息
        TestActivity: value: LiveData 
    }
    
  • 源码分为两个部分,第一个部分是注释1处的observer,第二个部分是注释2处的postValue赋值的地方。首先看注释1处的源码:
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //-----1-----
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //-----2-----
        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;
        }
        //-----3-----
        owner.getLifecycle().addObserver(wrapper);
    }
    
    • observer方法传入了两个参数,第一个是LifecycleOwner, 这个是负责管理生命周期的,另外一个参数则是Observer,是当数据发生变化时候的回调。对于LifeCycle不了解的可以看Android Jetpack架构组件(三)Lifecycle原理篇
    • 注释1的地方,会判断当前的生命周期,如果是处于DESTROYED阶段的话,就不会执行后面的逻辑代码,就不会注册进入作为观察者,这样就不用担心内存泄漏的问题。
    • 注释2处会生成一个LifecycleBoundObserver对象,它也是一个LifecycleObserver的实现类,主要负责LiveData的处理。然后将其放入mObservers中,mObservers内部是一个链表的形式存储的Entry,每一个Entry包含一个Key, Value,还有一个前Entry,和一个后Entry, 这样就形成了一个链表的结构。
    • 注释3处,调用getLifecycle().addObserver方法将LifecycleBoundObserver注册进入,便于后面在生命周期发生变化的时候回调,这个方法在Lifecycle原理篇已经详细的讲解过,可以点击查看,注册的逻辑其实就这么多,很简单,如果了解了Lifecycle的话非常简单。
  • 接下来我们先看一下生命周期发生变化时候的回调,这里先看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() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
    
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        	//-----1-----
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            //-----2-----
            activeStateChanged(shouldBeActive());
        }
    
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
    
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
    
    • Lifecycle原理篇中我们知道,当生命周期发生变化的时候,必然会调用LifecycleRegistry.ObserverWithState.dispatchEvent(LifecycleOwner owner, Event event)方法,从而运行mLifecycleObserver.onStateChanged(owner, event),这里实际运行的是LifecycleBoundObserver.onStateChanged(owner, event)方法,我们就从这里开始分析。
    • 注释1处首先判断当前的生命周期,如果是DESTROYED状态的话,就会移除观察者。所以我们不用担心在观察数据的时候内存泄漏的问题了。
    • 注释2处调用activeStateChanged(shouldBeActive())shouldBeActive()会判断当前的状态是不是STARTED或者RESUMED状态,如果不是这两个状态的话,就不会执行下面的逻辑。所以LiveData只会将通知发送到处于Active状态的组件。但是注意一点,这里State的STARTED和RESUMED状态实际上并不和Activity的生命周期一致,其中State的STARTED指的是Activity生命周期中的onStart()和onPause(),State的RESUMED指的是Activity生命周期中的onResume(),这些可以从源码LifecycleRegistry.getStateAfter得到。
  • 接着我们分析activeStateChanged方法,它在类ObserverWrapper中,是LifecycleBoundObserver的父类,下面看源码:
    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) {
        	//-----1-----
            if (newActive == mActive) {
                return;
            }
            //-----2-----
            mActive = newActive;
            //-----3-----
            boolean wasInactive = mActiveCount == 0;
            //-----4-----
            mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
            	//-----5-----
                onActive();
            }
            if (mActiveCount == 0 && !mActive) {
            	//-----6-----
                onInactive();
            }
            if (mActive) {
            	//-----7-----
                dispatchingValue(this);
            }
        }
    }
    
    • 注释1处首先判断当前组件是否处于相同的状态,如果是的话就会return.
    • 注释2将新的状态赋值给成员变量mActive,注释3处判断标记位是否当前处于Active的组件为0。
    • 注释4处根据mActive的状态为mActiveCount赋值,如果mActive为true就加1,否则就减1。
    • 注释5和6处主要用于自定义的LiveData以及MediatorLiveData。后面我们会讲解MediatorLiveData源码。
    • 注释7处调用了dispatchingValue,并且将自身传进去。
  • 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;
    }
    
    • 此方法会做一些判断,以及判断传入的ObserverWrapper是否为null, 但是最终都会进入considerNotify方法。下面我们看considerNotify的源码部分:
    private void considerNotify(ObserverWrapper observer) {
    	//-----1-----
        if (!observer.mActive) {
            return;
        }
        //-----2-----
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //-----3-----
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //-----4-----
        observer.mObserver.onChanged((T) mData);
    }
    
    • 注释1处首先会判断是否处于Active状态,如果不是的话就return, 然后注释2处判断当前observer组件的对应状态是否是active, 如果不是的话就传入false执行observer.activeStateChanged(false)
    • 注释3处将当前的版本和observer中的值进行比较,如果不符合要求就return。其实查看源码,这里mVersion的值想要改变,只能通过livedata.setValue或者livedata.postValue才能改变。所以如果仅仅是调用livedata.observer注册,而不调用这两个方法,是不会调用到注释4处真正的Observer回调的。
LiveData完整生命周期onCreate -> onDestory
  • 到这里,大部分的源码分析工作就结束了,但是以上只是按照逻辑全局分析,并没有具体的从常见的生命周期onCreate -> onDestory分析,下面我们将从生命周期的onCreate -> onDestory分析,如果仅仅调用开头例子中的livedata.observe的话,不调用postValue或者setValue的话,源码究竟是如何控制逻辑的?这也是最开始让我疑惑的一个问题。
  • 从上面的源码分析知道,当生命周期变化的时候都会依次执行activeStateChanged(shouldBeActive()) -> dispatchingValue(this) -> considerNotify(initiator) -> observer.onChanged(data)。下面我们按照生命周期开始一步一步分析。
  • onCreate, 因为这个生命周期shouldBeActive()为false, 所以在执行activeStateChanged第一行的时候满足都为false, 就会被return掉。
  • onStart, 这个生命周期的shouldBeActive()为true,在执行activeStateChanged的时候将mActive赋值true, 紧接着执行dispatchingValue -> considerNotify, 在considerNotify中,因为observer.mLastVersion >= mVersion 满足条件且都等于-1,所以这里会执行return。
  • onResume, 这个生命周期shouldBeActive()为true,但是在执行activeStateChanged第一行的时候,因为onStart中讲到了,将mActive已经赋值为true了,所以这里满足newActive == mActive, 就也会执行return逻辑。
  • onPause, 和onResume同理,也会执行return逻辑。
  • onStop,因为这个生命周期shouldBeActive()为false, 会执行onInactive方法,但是因为shouldBeActive()为false, 所以不会执行后面的dispatchingValue方法。
  • onDestory,在源码分析中我们知道, 如果处于这个生命周期的观察者是会被remove掉的
LiveData.setValue/postValue源码分析
  • 上面我们分析了没有执行postValue方法时候的源码,都不会执行我们想要的Observer回调,现在我们来分析常用的setValue/postValue时候的源码,源码如下:
    @MainThread
    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;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };
    
    • 从上面setValue源码可以看出,首先判断当前的线程是不是主线程,如果不是就会抛出异常。然后将mVersion加1,最后执行dispatchingValue(null)方法。
    • postValue方法就不限制主线程还是子线程,最终都会使用Handler机制,切换到主线程。执行mPostValueRunnable。实际执行的还是setValue。最终执行的也是dispatchValue(null)。由此可见setValuepostValue的区别。下面我们看dispatchingValue(null)是如何执行的:
      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(); ) {
                       //-----1-----
                      considerNotify(iterator.next().getValue());
                      if (mDispatchInvalidated) {
                          break;
                      }
                  }
              }
          } while (mDispatchInvalidated);
          mDispatchingValue = false;
      }
       
      private void considerNotify(ObserverWrapper observer) {
          if (!observer.mActive) {
              return;
          }
          if (!observer.shouldBeActive()) {
              observer.activeStateChanged(false);
              return;
          }
          if (observer.mLastVersion >= mVersion) {
              return;
          }
          observer.mLastVersion = mVersion;
          //-----2-----
          observer.mObserver.onChanged((T) mData);
      }
      
      • 上面传入的参数为null时候,会遍历mObservers执行注释1处的considerNotify
      • 因为我们执行了postValue或者setValue方法,所以mVersion会加1,并且当时处于onResume状态,所以注释2处直接会被执行。也就是说当我们的数据源一旦发生了变化,就会直接执行自定义的Observer回调,这样就保证了数据的即时性,并且兼顾了生命周期,这也就是LiveData组件的本质意义。
Transformations.map()的源码分析
  • 上一篇LiveData使用篇我们讲到了Transformations.map()的使用,这里我们粘贴一下上一篇的源码部分:

    class TestActivity : AppCompatActivity() {
    
        private val mutableLiveData = MutableLiveData<String>()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            mutableLiveData.observe(this, Observer {
                Log.d(TAG, "Changed1:$it")
            })
    
            val mediatorLiveData: LiveData<String> = Transformations.map(mutableLiveData) {
                "$it+map"
            }
            mediatorLiveData.observe(this, Observer {
                Log.d(TAG, "Changed2:$it")
            })
        }
    
        fun onTest(view: View) {
            mutableLiveData.postValue("LiveData")
        }
    }
    
    • 这里我们直接看map的源码:
    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }
    
    • 这里涉及到了另一个LiveData的实现类MediatorLiveData,此处调用了addSource,然后在Observer的回调中调用了自身的result.setValue(data)方法,MediatorLiveData的源码没多少,这里我们贴出来:
    public class MediatorLiveData<T> extends MutableLiveData<T> {
        private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();
        
        @MainThread
        public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
            Source<S> e = new Source<>(source, onChanged);
            Source<?> existing = mSources.putIfAbsent(source, e);
            if (existing != null && existing.mObserver != onChanged) {
                throw new IllegalArgumentException(
                        "This source was already added with the different observer");
            }
            if (existing != null) {
                return;
            }
            if (hasActiveObservers()) {
                e.plug();
            }
        }
    
        @MainThread
        public <S> void removeSource(@NonNull LiveData<S> toRemote) {
            Source<?> source = mSources.remove(toRemote);
            if (source != null) {
                source.unplug();
            }
        }
    
        @CallSuper
        @Override
        protected void onActive() {
            for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
                source.getValue().plug();
            }
        }
    
        @CallSuper
        @Override
        protected void onInactive() {
            for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
                source.getValue().unplug();
            }
        }
    
        private static class Source<V> implements Observer<V> {
            final LiveData<V> mLiveData;
            final Observer<? super V> mObserver;
            int mVersion = START_VERSION;
    
            Source(LiveData<V> liveData, final Observer<? super V> observer) {
                mLiveData = liveData;
                mObserver = observer;
            }
    
            void plug() {
                mLiveData.observeForever(this);
            }
    
            void unplug() {
                mLiveData.removeObserver(this);
            }
    
            @Override
            public void onChanged(@Nullable V v) {
                if (mVersion != mLiveData.getVersion()) {
                    mVersion = mLiveData.getVersion();
                    mObserver.onChanged(v);
                }
            }
        }
    }
    
    • 上面我们看到其中有一个SafeIterableMap的成员变量mSources, 在上一篇中说到,它以链表的形式存储的是待观察的LiveData。上面addSource方法就是将LiveData对象存储的操作。在addSource第一行我们看到有一个重要的类Source,它里面封装了待观察的LiveData还有Observer对象。
    • 下面我们一步一步分析一下上面Transformations.map()也就是MediatorLiveData是如何实现观察数据的。
    • 在生命周期为onStart的时候,前面分析过了会执行livedata.onActive()方法,LiveData自身的onActive实现为空,但是我们这里是MediatorLiveData,onActive的实现就不为空了,源码如下:
    protected void onActive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();
        }
    }
    
    void plug() {
        mLiveData.observeForever(this);
    }
    
    • 从上面可以看出,最终执行的是mLiveData.observeForever方法,源码如下:
    @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);
    }
    
    • observeForeverobserver从方法名字可以看出区别,observeForever方法是永远绑定可观察的,它内部的AlwaysActiveObserver类的shouldBeActive永远为true,而observe方法中的LifecycleBoundObserver类的shouldBeActive会判断生命周期。
    • 到这里执行完observeForever之后,就将上面测试代码中的mediatorLiveDatamutableLiveData仅仅的联系在了一起,这时候如果你debug就会发现,mutableLiveData中这时候有两个ObserverWrapper,一个是调用mediatorLiveData.observe生成的LifecycleBoundObserver,另一个是上面调用mediatorLiveData.addSource时候,当生命周期执行到了onStart时候,会执行source.plug(),因为source中存储的是mediatorLiveData对象,实际上执行的是还是mediatorLiveData.observeForever方法,所以第二个就是observeForever中生成的AlwaysActiveObserver
    • 这时候我们如果调用mutableLiveData.postValue的话,会遍历LiveData中的mObservers,首先会执行上面第一个LifecycleBoundObserver的回调。
    • 然后执行第二个AlwaysActiveObserver的回调,因为在mediatorLiveData中的mSources也存储着同样的Observer回调,mutableLiveData中的第二个ObserverWrapper中的Observer就是从mediatorLiveData.source.plug()传进去的,我们再来看下Source源码进行分析:
    private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;
        final Observer<? super V> mObserver;
        int mVersion = START_VERSION;
    
        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData;
            mObserver = observer;
        }
    
        void plug() {
            mLiveData.observeForever(this);
        }
    
        void unplug() {
            mLiveData.removeObserver(this);
        }
    
        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                //-----1-----
                mObserver.onChanged(v);
            }
        }
    }
    
    • 所以这里会执行上面注解1处的mObserver.onChanged,这个mObserver就是我们调用Transformations.map(data)时候,进而调用addSource存入的,源码如下:
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
           		//-----1-----
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }
    
    • 所以也就会执行上面注释1处的result.setValue,这个result最终被返回,也就是我们测试代码中的mediatorLiveData,调用result.setValue的逻辑我们就不分析了,前面分析多次了。最终也就执行了mediatorLiveData的数据监听回调。
    • 当执行onStop生命周期的时候,会执行mediatorLiveDataonInactive方法将AlwaysActiveObserver移除。
    • 当执行onDestory生命周期的时候,在onStateChanged也会执行removeObserver(mObserver),所以就不会有内存泄漏的风险。

总结

  • Transformations.switchMap的源码部分和上面分析的Transformations.map基本一样,就不赘述了。
  • LiveData真的是一个很好用的组件,既可以分开用,也可以组合其它的ViewModel组件使用。
  • LiveData 具有生命周期感知能力,这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
  • LiveData数据源发生变化的时候会立马回调,对UI进行更新,保证了数据的即时性。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Jetpack是Google提供的一套用于加速Android应用开发的工具包,其包括了许多架构组件,其之一就是ViewModel。 ViewModel是一种设计模式,用于保存和管理与UI相关的数据。在传统的Android开发,当屏幕旋转或者因为其他原因导致Activity或Fragment重建时,之前保存的临时数据就会丢失。而ViewModel的出现解决了这个问题。 ViewModel的主要作用是将数据与UI组件分离。它的工作方式是创建一个ViewModel类,并在其保存需要与UI组件交互的数据。这样,当屏幕旋转或重建时,ViewModel实例不会销毁,数据也会得到保留。然后,在Activity或Fragment,通过获取ViewModel实例,可以轻松地访问这些数据。 使用ViewModel的好处有很多。首先,它可以避免内存泄漏,因为ViewModel的生命周期与Activity或Fragment无关。其次,它可以节省资源,因为当Activity或Fragment销毁时,ViewModel实例可以被系统缓存起来,下次再创建时可以直接返回该实例。另外,由于ViewModel保存了与UI相关的数据,可以减少因为屏幕旋转导致的数据重复加载的问题。 在使用ViewModel时,你可以选择使用Android Jetpack的其他架构组件来进一步提高开发效率,比如通过LiveData实现数据的观察和通知,或者通过DataBinding来实现UI与数据的自动绑定。 总之,ViewModel是Android Jetpack非常重要的一个架构组件,它的出现实现了数据与UI的解耦,提高了开发效率,并且解决了数据丢失的问题。希望通过这篇文档的详解,你对ViewModel有了更深入的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值