欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android LiveData(二):源码分析

程序员文章站 2024-03-03 19:42:28
...

有上文对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方法,

Android LiveData(二):源码分析

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

Android LiveData(二):源码分析

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哦

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接口回调。

上一篇: java递归法求字符串逆序

下一篇: