Android JetPack深入分析LiveData源码

前言

Google Android开发者 LiveData概览

在了解LiveData源码之前,建议先了解LifeCycle相关知识,请参考:Android JetPack深入分析Lifecycle源码

定义

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

从定义中,我们可以大概知道:LiveData是一个数据存储类,能够感知ActivityFragment等组件的生命周期,并且支持对它存储的数据进行观察;

使用LiveData的好处以及如何使用这里就不再过多赘述,更多查看Google官方文档;

这里就直接进入正题,源码分析LiveData是如何实现生命周期监听以及数据更新的;

绑定观察者

调用LiveData.observe()方法会进行对应观察者绑定,相关代码如下:

	  private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
		
	//LifecycleOwner对应被观察者,Observer对应观察者
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    	//1.进行主线程判断,不是主线程中调用直接抛异常;
        assertMainThread("observe");
        //2.如果被观察者已销毁,则直接返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            return;
        }
        //3.将观察者和被观察者包装成LifecycleBoundObserver对象
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //4.mObservers是以Observer为key,LifecycleBoundObserver为value的,内部采用双链表结构存储,根据传入的观察者Observer查询LifecycleBoundObserver,如果没查到,则将observer, wrapper以Entry<K,V>形式插入到链表中,如果已存在,则直接返回对应的ObserverWrapper
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //5.如果链表中已存在&&绑定的是同一个被观察者,则抛异常;
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //6.如果已存在,则直接返回
        if (existing != null) {
            return;
        }
        //7.由前面的Lifecycle源码分析可知,最终将wrapper添加到LifecycleRegistry中维护的观察者集合中;
        owner.getLifecycle().addObserver(wrapper);
    }

其中LifecycleBoundObserver类相关代码如下:

	//1.实现了LifecycleEventObserver接口,而我们知道LifecycleEventObserver继承于LifecycleObserver,因此上述可以将LifecycleBoundObserver存储到LifecycleRegistry中维护的观察者集合中;
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }
		//当前被观察者是否处于活跃状态,即state应该>=STARTED,对应STARTED和RESUMED两种状态
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
		
		//Lifecycle源码分析中,分发生命周期事件的时候,会执行此onStateChanged方法
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }
		
		//判断是否绑定过的为同一被观察者
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
		
		//解绑观察者
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
	
	//内部维护了 观察者、观察者活跃标志、观察者对应版本号信息
    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;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

小结

从上面源码分析,我们可以知道,LiveData绑定观察者会将观察者以及被观察者包装LifecycleBoundObserver对象【内部持有观察者被观察者观察者版本号观察者活跃标志等信息】,并在其内部维护了一个双向链表结构用于存储LifecycleBoundObserver对象,最终会将观察者添加到LifecycleRegistry维护的观察者集合中,从而实现生命周期的监听!!!

更新数据

LiveData.postValue最终调用的也是LiveData.setValue()方法,只是做了下切换到主线程,这里就直接看LiveData.setValue()方法;

public abstract class LiveData<T> {
	//当前LiveData对应的版本号
	private int mVersion;
	//当前是否正在刷新数据
    private boolean mDispatchingValue;
	//刷新标记
    private boolean mDispatchInvalidated;

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

setValue方法主要做了以下几件事:

  • 判断执行线程是否是主线程;
  • 当前版本号+1;
  • 将传入的value设置给全局变量mData;
  • 执行dispatchingValue(null)进行数据分发;

我们紧接着看下dispatchingValue(null)方法:

    void dispatchingValue(@Nullable ObserverWrapper initiator) { 
    	//1.如果正在刷新数据,标记之前的刷新数据无效,mDispatchInvalidated = true会影响正在for循环中的逻辑
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        //2.设置正在刷新
        mDispatchingValue = true;
        do {
         	//3.修改刷新非法标记为false
            mDispatchInvalidated = false;
            if (initiator != null) {
            	//4.如果传入initiator,表示只通知对应的观察者更新数据
                considerNotify(initiator);
                initiator = null;
            } else {
            	//5.遍历所有观察者,调用considerNotify方法进行数据更新;
            	//这里是do-while逻辑,会先执行一遍do操作,遍历所有的观察者进行数据更新,如果在更新过程中再次调用了setValue方法
            	//则会先跳出循环,重新遍历所有观察者通知数据更新【mDispatchInvalidated为true】
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

dispatchingValue()方法中会判断mDispatchingValue【当前是否正在分发数据】,如果不是则遍历所有观察者进行分发,如果当前正在分发数据【setValue方法没执行完被再次调用】,则会先跳出观察者遍历,重新进行一次观察者遍历数据分发;【假设initiator传入为null】,具体数据更新由considerNotify方法完成;

    private void considerNotify(ObserverWrapper observer) {
    	  // 1.active状态检查
        if (!observer.mActive) {
            return;
        }
        //2.判断当前观察者是否处于活跃状态【被观察者生命周期状态为STARTED,RESUMED】
        if (!observer.shouldBeActive()) {
			//3.设置mActive为false,不回调onChanged方法;
            observer.activeStateChanged(false);
            return;
        }
        //3.版本比对,mLastVersion默认为-1,而mVersion默认为0,因此会导致粘性事件产生【后注册的观察者会接收到前面的数据更新操作】,如果不想粘性,这里可以通过hook修改mLastVersion和mVersion一致实现;
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        //4.同步观察者版本号和LiveData版本号一致;
        observer.mLastVersion = mVersion;
        //5.回调观察者对应的onChanged方法
        observer.mObserver.onChanged((T) mData);
    }

considerNotify()方法中会进行生命周期活跃版本号判断,满足条件,最终会回调Observer.onChanged()方法!!!

更新数据流程图

更新数据流程图

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值