Android LiveData(二):源码分析

有上文对LiveData的基本认识,接下来直接进入LiveData的源码分析,首先进入observer方法,需要注意的是MainActivity继承AppCompatActivity,是LifecycleOwner接口实现类的子孙。而调用observer方法时传入当前MainActivity的上下文,可以理解为owner就是当前的MainActivity。

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        //判断当前LifecycleOwner即Activity的生命周期状态,如果为DESTROYED就没必要执行了
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
    	//注释2
    	//对传入的observer封装为LifecycleBoundObserver,类比Handler机制中将Runnable封装为Message
        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;
        }
    	//注释3
    	//owner就是LifecycleOwner,而我们MainActivity的父类AppCompatActivity 是LifecycleOwner
    	//的实现类ComponentActivity的子类,即给我们的MainActivity注册了一个与声明周期相关的观察者
    	//LifecycleObserver,这样一来就能感知组件的生命周期了。也就是说我们的MainActivity声明周期
        //发生变化的时候,会回调wrapper接口,即回调observer接口,也就是触发观察者中的逻辑
        owner.getLifecycle().addObserver(wrapper);
    }

在注释2处,对观察者observer做了一层封装,集合中保存的是wrapper。注释3处,通过addObserver注册了生命周期的观察监听,到这里我们就大概知道,postValue会触发observer方法,组件即MainActivity生命周期发生变化的时候,也会触发observer方法,具体流程接着往下看。

接下来就从postValue方法发送数据,触发观察者接口回调的流程进行简单分析。进入postValue方法:

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    //注释
    //切换到主线程执行
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

也就是说postValue无论在哪个线程执行,都会切换到主线程去执行。意味着它可以在子线程去发送数据,接着往下看,它里面调用了setValue方法,

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //noinspection unchecked
        setValue((T) newValue);
    }
};

原来postValue只不过是对setValue方法进行了封装,切换线程,结论就是setValue只能在主线程执行,而postValue即可以在主线程也可以在子线程执行。

接下来进入setValue方法:

protected void setValue(T value) {
    assertMainThread("setValue");
    //注释1
    mVersion++;
    mData = value;
    //注释2
    dispatchingValue(null);
}

setValue方法里面主要关注两处注释处代码即可,注释1处代码后面设计再分析,先进入dispatchingValue方法,

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

注意setValue方法中dispatchingValue方法传入参数为null,进入下面注释1处逻辑,如果传入参数不为null,进入注释2处逻辑,遍历所有注册的观察者,执行considerNotify方法:

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

mLastVersion和mVersion的初始值均为-1,前面提到过在setValue方法注释1处mVersion++,此时mVersion>mLastVersion, 才会执行注释3处代码,触发接口Observer回调onChanged方法,但是 observer.mLastVersion = mVersion;这一行代码,表示注释3处的代码只会执行一次。

那么问题来了,MainActivity是如何感知生命周期的呢?如何做到先执行postValue方法,后注册观察者依然能触发接口回调的呢?我们目前已知的是前面提到过,在observer方法的注释3处,给owner即MainActivity注册了生命周期的监听接口LifecycleObserver,当生命周期发生改变时,会回调LifecycleBoundObserver的onStateChanged方法,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-toL6MrPv-1605590968507)(C:\Users\dell\Desktop\层级关系.png)]

在该方法中打断点,debug调试,效果如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T7xWFb7M-1605590968510)(F:\oCamFile\生命周期.gif)]

MainActivity依次调用生命周期方法onCreate()、onStart()、onResume(),会触发ononStateChanged的多次调用,也就是会多次调用activeStateChanged方法。

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        ...
		//注释1
        //该方法返回最近调用的生命周期状态
        //例如绑定的MainActivity如果被销毁或处于不可见状态,返回false
        //那么activeStateChanged方法中dispatchingValue(this)将不会执行
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
		//生命周期发生改变就会回调到这个方法,
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            //如果生命周期DESTROYED,即已经销毁了,就需要将注册的观察者移除
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            //注释2
            //如果没有被销毁,生命周期发生改变的回调
            activeStateChanged(shouldBeActive());
        }

        ...
    }

activeStateChanged方法代码如下,需要重点关注注释1处的dispatchingValue方法,注意是参数不为null哦,即postValue或setValue触发的dispatchingValue方法,参数为null,而宿主生命周期状态改变触发的回调,调用dispatchingValue方法参数不为null

void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
        return;
    }
    // immediately set active state, so we'd never dispatch anything to inactive
    // owner
    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) {
        //注释1
        dispatchingValue(this);
    }
}

再次回到dispatchingValue方法,参数不为null,进入对应的considerNotify方法,还是会根据observer.mLastVersion >= mVersion 来判断是否会继续执行,触发considerNotify方法注释3处的代码,即回调observer的onChanged方法。只有当postValue或setValue执行过了,才会触发,现在就应该清楚了,即使先调用postValue,后注册观察者,生命周期的接口回调会触发Observer接口回调。

considerNotify方法,还是会根据observer.mLastVersion >= mVersion 来判断是否会继续执行,触发considerNotify方法注释3处的代码,只会执行一次,即回调observer的onChanged方法。只有当postValue或setValue执行过了,才会触发,现在就应该清楚了,即使先调用postValue,后注册观察者,生命周期的接口回调会触发Observer接口回调。
为了更适合常规的应用场景,可对LiveData进行相关改造,更适合常规应用场景,只有先注册了观察者,执行postValue或setValue方法时,才会触发监听,代码建如下链接
https://github.com/xpf-android/Modular_Router/blob/master/common/src/main/java/com/xpf/common/LiveDataBus.java

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值