Jetpack组件,如今是google力推的架构模式,它能够帮助我们快速构建项目,在JectPack丰富的组件当中,生命周期几乎是贯穿全部,万物皆始于声明周期,从本章开始,就开始深入JectPack核心组件源码
看到LiveData这个名字,第一感觉这是一个数据类,其实不是的,LiveData是能够持有任意一种数据并且能够对这个数据进行观察。在LiveData之前,我们通过回调的方式获取网络请求返回的数据,从而进行View的数据展示,MVP架构就是采用这种原理,可为什么MVP越来越不受待见,是因为大量的数据接口编写,以及可能出现的回调地狱(这也是其中一个原因,不是全部)。
LiveData采用的观察者模式,能够感知数据的变化,从而通过数据驱动UI,这也是MVVM架构的核心思想,其实你也可以看做是接口的回调;除此之外,LiveData具备生命周期感知能力,只有在Activity或者Fragment处于活跃状态时,才会回调数据,能够避免内存泄漏。
public class MutableLiveData extends LiveData {
/**
* Creates a MutableLiveData initialized with the given {@code value}.
*
* @param value initial value
*/
public MutableLiveData(T value) {
super(value);
}
/**
* Creates a MutableLiveData with no value assigned to it.
*/
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
如果使用过LiveData的伙伴应该了解,在创建一个LiveData对象的时候,通常是创建了一个MutableLiveData对象,这个类是LiveData的子类,然后重写了LiveData实现的两个方法postValue和setValue。
首先LiveData是一个抽象类,不能被初始化,因此不能直接调用这两个方法,所以声明了一个子类MutableLiveData来调用父类的方法。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
首不看具体的实现,在postValue方法中,涉及到了线程切换,postToMainThread切换到了主线程,也就是说在子线程发送数据,需要使用postValue方法
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
其实从源码中也能看到,其实postValue最终也是调用了setValue方法
接下来我们深入源码,看下数据是如何分发传递的,首先从postValue开始,因为postValue最终也是调用了setValue。
首先我们传入一个value值,这个值是一个泛型;因为postValue能在任意线程中调用,因此涉及到线程同步,这里加了一把锁;这里有一个标志位postTask,因为mPendingData默认值就是NOT_SET,是一个空的Object对象,所以postTask为true;
volatile Object mPendingData = NOT_SET;
static final Object NOT_SET = new Object();
紧接着,是把我们传入的值,赋值给了mPendingData,因为postTask == true,因此直接调用
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
切换到主线程,把mPendingData传给了newValue的同时,将mPendingData重新设置为NOT_SET,最终调用了setValue方法,其实就是将我们调用postValue传入的值,最终传给了setValue。
在setValue方法中,将传入的值赋值给了mData,mData就是LiveData中真正的数据持有者
接下来我们看到,在setValue中执行了dispatchingValue方法,传入了参数null,这个比较关键,我们看下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, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
在dispatchingValue方法中,执行了一个do-while循环,因为一开始initiator传入的就是空的,那么会走到else,这里我们可以看到一个for循环遍历mObservers数组中的全部观察者,因为LiveData可以被多个观察者注册监听,因此采用了mObservers数组保存所有的观察者,当数据发生变化时,所有的观察者都能接收到数据。
当拿到其中一个观察者之后,会调用considerNotify方法,传入的就是在注册观察者的时候创建的LifecycleBoundObserver对象,后面会讲到,这里提前透露一下
private void considerNotify(ObserverWrapper observer) {
1️⃣
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
2️⃣
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
3️⃣
if (observer.mLastVersion >= mVersion) {
return;
}
4️⃣
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
1️⃣ 2️⃣ 3️⃣:这个我们放在后面说,很重要的一个版本号机制
4️⃣:最终我们可以看到,considerNotify方法中调用了观察者的onChanged方法,并把mData传了进去,mData之前我们说过,其实就是我们传入的数据,也是LiveData真正的数据持有者
既然通过postValue或者setValue,最终将我们传入的数据赋值给了LiveData中的一个数据持有者mData,那么我们怎么能够观察这个数据的变化呢?LiveData提供了一个observe方法用来注册观察者。
liveData.observe(this, new Observer() {
@Override
public void onChanged(Object o) {
}
});
那么我们接下来就关注一下,LiveData如何注册观察者并能够感知生命周期
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
1️⃣
assertMainThread("observe");
2️⃣
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
3️⃣
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;
}
4️⃣
owner.getLifecycle().addObserver(wrapper);
}
在observe的源码中,我们首先看应用层传入的两个参数:
owner:对应的Activity或者Fragment,或者实现了LifecycleOwner接口的组件
observer:创建的观察者对象,其实本身就是一个接口,是一个匿名内部类
1️⃣:在注册观察者的时候,必须要保证是在主线程中注册,否则断言就会抛出异常;
2️⃣:判断当前组件的生命周期是否处于销毁状态,如果属于DESTROYED状态,那么就不会注册观察者,直接return
3️⃣:在这里是将我们传入的两个参数封装成了一个LifecycleBoundObserver对象
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@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(@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);
}
}
其中owner是LifecycleBoundObserver持有,观察者observer则是交给了父类的构造方法,LifecycleBoundObserver的父类是ObserverWrapper
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;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
我们可以看到,ObserverWrapper是持有了observer的引用,因为LifecycleBoundObserver跟ObserverWrapper是继承关系,因此也相当于LifecycleBoundObserver持有了observer的引用。
继续看,在创建了LifecycleBoundObserver之后,是将其放入一个mObservers的map集合中,key是observer,value是LifecycleBoundObserver
private SafeIterableMap, ObserverWrapper> mObservers =
new SafeIterableMap<>();
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
其中调用putIfAbsent方法,主要就是为了判断当前观察者是否已经被注册过了,如果已经存在这个key,那么返回的就不为空;
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry entry = get(key);
if (entry != null) {
return entry.mValue;
}
put(key, v);
return null;
}
因此在后续判断中,会判断如果返回值不为空,那么就会抛出异常,不能重复注册
4️⃣:最终获取组件的生命周期对象,并将LifecycleBoundObserver作为观察者传进去了,这也就意味着,观察者具备了感知当前组件生命周期的能力
public abstract void addObserver(@NonNull LifecycleObserver observer);
我们可以看到,addObserver需要传入的是一个LifecycleObserver对象,这也就意味着,LifecycleBoundObserver就是这个LifecycleObserver的一个子类,我们看下上面的源码,可以看到LifecycleBoundObserver实现了LifecycleEventObserver的接口
public interface LifecycleEventObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
所以,我们可以这么理解,只要我们实现了这个接口,并且作为观察者交给组件,就能感知组件的生命周期,我们可以尝试一下。
首先我们创建一个观察者对象,实现LifecycleEventObserver接口
public class MyLifeCycle implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
Log.e("TAG","event -------"+event);
//感知组件的生命周期
if(source.getLifecycle().getCurrentState() == Lifecycle.State.CREATED){
Log.e("TAG","-------CREATED");
}else if(source.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED){
Log.e("TAG","-------RESUMED");
}
}
}
然后作为观察者添加到组件中,这里拿MainActivity为例
this.getLifecycle().addObserver(new MyLifeCycle());
这样的话,就能感知MainActivity的生命周期,就不需要手动去onResume或者onDestory中去做相关的处理逻辑
2022-06-04 13:21:54.741 24751-24751/com.t.demo02 E/TAG: onCreate
2022-06-04 13:21:54.743 24751-24751/com.t.demo02 E/TAG: event -------ON_CREATE
2022-06-04 13:21:54.743 24751-24751/com.t.demo02 E/TAG: -------CREATED
2022-06-04 13:21:54.745 24751-24751/com.t.demo02 E/TAG: event -------ON_START
2022-06-04 13:21:54.750 24751-24751/com.t.demo02 E/TAG: event -------ON_RESUME
2022-06-04 13:21:54.750 24751-24751/com.t.demo02 E/TAG: -------RESUMED
所以LiveData之所以能够感知生命周期,就是因为LifecycleBoundObserver这个封装类实现了LifecycleEventObserver接口,并添加为组件生命周期的观察者,因此具备了感知生命周期的能力。
好的,既然LifecycleEventObserver被LifecycleBoundObserver实现,那么必然也实现了onStateChanged这个方法,我们去看一下。
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
1️⃣
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
2️⃣
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
在这个方法中,就能回调组件的生命周期
1️⃣:这里拿到了组件当前的状态getCurrentState,会判断,如果当前组件已经是销毁的状态,那么就会将mObserver从mObservers中移除,mObservers就是LiveData中用来保存观察者的Map数组;所以当页面重新加载之后,会重新注册新的观察者。
这个也是LiveData能够避免内存泄漏的原因
@MainThread
public void removeObserver(@NonNull final Observer super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
removed.activeStateChanged(false);
}
2️⃣:因为只要每次组件的生命周期发生变化,这个方法就会被回调,因此这里是进行了状态的前后关系比较,这里while循环肯定能进去,并将prevState设置为当前组件的生命周期状态,然后调用了activeStateChanged方法,这里就是产生粘性事件的原因所在。
我们来看个一个场景
MutableLiveData liveData = new MutableLiveData();
liveData.postValue("11111");
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
liveData.observe(MainActivity.this, new Observer() {
@Override
public void onChanged(Object o) {
Log.e("TAG----","result"+o);
}
});
}
});
当通过LiveData发送数据之后(这里注意,我并没有注册观察者),通过点击按钮,注册观察者,这个时候发现居然收到了之前发送的消息。
按照正常的逻辑,我只有注册之后,你发送的消息我才能收到;为啥先发消息后注册也能收到呢?这就是粘性事件,使用过EventBus的伙伴应该熟悉,EventBus也存在粘性事件的场景。
首先粘性事件既然发生,那么回到第一小节的地方,我们知道在onChanged中肯定回调了数据,所以肯定是某个地方调用了dispatchingValue方法,通过源码我们可以看到除了setValue之外,在ObserverWrapper中activeStateChanged方法中调用了dispatchingValue,因为ObserverWrapper是个抽象类,因此肯定其子类能够调用。
最终定位就是在LifecycleBoundObserver的onStateChanged方法中执行了,我们知道当组件的生命周期发生变化后,这个方法会回调;
所以这里会有一个疑问❓我在点击按钮的时候,MainActivity的生命周期已经走到onResume,不会再触发onStateChanged了吧,是这样吗
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// liveData.observe(MainActivity.this, new Observer() {
// @Override
// public void onChanged(Object o) {
// Log.e("TAG----","result"+o);
// }
// });
MainActivity.this.getLifecycle().addObserver(new MyLifeCycle());
}
});
拿我们之前在添加自定义观察者时的代码,我们也试一下,跟我们想象的好像不太一样,onStateChanged回调居然走了一遍!!
也就是说,当我点击按钮,注册一个LiveData的观察者的时候,onStateChanged也会被回调,意味着dispatchingValue可能会被执行。
这个时候,dispatchingValue传入的参数不为空,同样会调用considerNotify方法,最终在观察者的onChanged方法中回调。
还有一个问题就是,每次注册观察者,onStateChanged会被回调三次,onCreate - onStart - onResume,那么为什么在onChanged中只会被回调一次
public class MyLifeCycle implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
Lifecycle.State currentState = source.getLifecycle().getCurrentState();
Log.e("TAG--------","currentState ---"+currentState);
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
Log.e("TAG--------","prevState ---"+prevState);
currentState = source.getLifecycle().getCurrentState();
Log.e("while TAG--------","currentState ---"+currentState);
}
}
}
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/TAG--------: currentState ---CREATED
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/TAG--------: prevState ---CREATED
2022-06-04 15:50:35.544 9863-9863/com.t.demo02 E/while TAG--------: currentState ---CREATED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/TAG--------: currentState ---STARTED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/TAG--------: prevState ---STARTED
2022-06-04 15:50:35.546 9863-9863/com.t.demo02 E/while TAG--------: currentState ---STARTED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/TAG--------: currentState ---RESUMED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/TAG--------: prevState ---RESUMED
2022-06-04 15:50:35.550 9863-9863/com.t.demo02 E/while TAG--------: currentState ---RESUMED
这里就回到了第一小节讲到的一个版本号机制
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
这里我们看到就是当onChanged被回调一次之后,观察者的mLastVersion就被赋值为mVersion,当再次进来之后,因为mLastVersion == mVersion就直接return了。
我们看一下这个版本号,首先mLastVersion是ObserverWrapper的成员变量,默认值是-1;mVersion是LiveData的一个成员变量,如果是调用的空参构造方法,默认值也是-1,如果非空参构造方法,那么就就会将版本号+1,而且会把初始值赋值给mData,我们使用时一般都是采用空参构造方法。
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;
}
/**
* Creates a LiveData with no value assigned to it.
*/
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;
}
所以在一开始,mLastVersion和mVersion都是-1,当调用setValue的时候,mVersion++
mVersion = 0;
mLastVersion = -1;
把判断条件放在这儿
if (observer.mLastVersion >= mVersion) { return; }
这个时候 mLastVersion < mVersion,会继续往下走,这时onChanged就会被回调,观察者获取到值,此时的版本号如下。
mVersion = 0;
mLastVersion = 0;
所以我们之前讲到的,注册一个观察者会走onStateChanged三次回调,可为什么只回调了一次数据,原因就在这里了,当再次走到这个判断的时候,mLastVersion == mVersion,直接return。
通过版本号机制,就是用来防止组件生命周期变化,导致观察者重复接收多次LiveData的数据。
所以,观察者接收数据的方式有2种:
1 postValue / setValue
2 当组件的生命周期发生改变或者我们第一次注册观察者时
像实际的开发中,我们使用LiveData不仅仅局限于当前页面的数据展示,包括跨组件、跨页面的通信,同样会使用到LiveData,那么通过LiveData来实现一个事件总线,熟悉使用EventBus的伙伴应该都清楚
/**
* 事件总线
*/
public class LiveDataBus {
//当前应用全部的LiveData集合
private Map> map;
private static LiveDataBus liveDataBus;
private LiveDataBus(){
map = new HashMap<>();
}
public static LiveDataBus getInstance(){
if(liveDataBus == null){
synchronized (LiveDataBus.class){
if(liveDataBus == null){
liveDataBus = new LiveDataBus();
}
}
}
return liveDataBus;
}
public MutableLiveData with(String key,Class clazz){
if(!map.containsKey(key)){
map.put(key, new MutableLiveData<>());
}
return (MutableLiveData) map.get(key);
}
}
with方法用于创建新的LiveData对象或者直接返回已有的LiveData对象
MutableLiveData liveData1 = LiveDataBus.getInstance().with("key", String.class);
liveData1.postValue("1234567");
记不记得之前的小结中,提到的粘性事件,其实官方的LiveData就是存在这个粘性事件的,所以在实际的开发中,这种跳转页面传递参数没有问题,但是如果某些场景就不能使用这种粘性事件,那么官方的LiveData就不能使用了,需要我们自己去处理粘性事件。
前面提到过,粘性事件产生的主要原因就是,在注册观察者的时候,就会导致数据的回调,那么我们是不是可以在数据回调之前,就将观察者的版本号修改成与LiveData的版本号保持一致,是不就可以。
public class MyLiveData extends MutableLiveData {
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer,Boolean isSticky) {
super.observe(owner, observer);
//如果不需要粘性事件
if(isSticky){
observe(owner,observer);
}
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
//hook
try {
hookObserver(observer);
}catch (Exception e){
}
}
private void hookObserver(Observer super T> observer) {
Class aClass = LiveData.class;
//
try {
Field mObserversFiled = aClass.getDeclaredField("mObservers");
mObserversFiled.setAccessible(true);
//获取mObservers数组
Object mObservers = mObserversFiled.get(this);
//通过observer来获取创建的LifecycleBoundObserver
Method getMethod = mObservers.getClass().getDeclaredMethod("get",Object.class);
getMethod.setAccessible(true);
//获取到LifecycleBoundObserver
Object wrapper = null;
Object entry = getMethod.invoke(mObservers,observer);
if(entry != null && entry instanceof Map.Entry){
wrapper = ((Map.Entry, ?>) entry).getValue();
}
if(wrapper == null){
Log.e("TAG","没有获取到相应的LifecycleBoundObserver");
}
//获取到mLastVersion
Field mLastVersionFiled = wrapper.getClass().getSuperclass().getDeclaredField("mLastVersion");
mLastVersionFiled.setAccessible(true);
//获取LiveData的mVersion
Field mVersionFiled = aClass.getDeclaredField("mVersion");
mVersionFiled.setAccessible(true);
Object mVersion = mVersionFiled.get(this);
//赋值
mLastVersionFiled.set(wrapper,mVersion);
}catch (Exception e){
Log.e("TAG","ecp --- "+e);
}
}
}
这里是重写了LiveData,并且传入了一个参数isSticky来确认是否需要粘性事件,如果需要粘性事件,那么就直接走正常的LiveData的注册逻辑;
如果不需要粘性事件,那么其实就是通过hook的方式来修改观察者observer的版本号mLastVersion等于LiveData的版本号mVersion,基本的反射操作,其实通过前面的源码讲解,这块就非常简单了。
大家其实没必要担心hook之后影响当前组件的数据发送,因为每次post或者set都会增加mVersion的版本号,肯定是能够回调onChanged方法!
其实在LiveData的源码中,我们已经接触到了LifeCycle,其实LifeCycle的出现,真的是极大地解放了我们的双手,能够动态感知组件的生命周期,那么LifeCycle是怎么做到的呢?
owner.getLifecycle().addObserver(wrapper);
我们拿LiveData中observe方法的最后一行代码入手,首先调用了getLifecycle方法
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
LifeCycle是一个抽象类,获取到的肯定是它的一个子类,我们先从Activity组件入手,看看getLifecycle拿到的是什么。
public Lifecycle getLifecycle() {
// Instead of directly using the Activity's Lifecycle, we
// use a LifecycleRegistry that is nested exactly outside of
// when Fragments get their lifecycle changed
// TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
return mFragmentLifecycleRegistry;
}
通过FragmentActivity源码中的getLifecycle方法我们得知,getLifecycle拿到的是一个LifecycleRegistry对象,它就是LifeCycle的一个子类。
其实调用addObserver,就是调用了LifecycleRegistry的addObserver方法
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
1️⃣
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
2️⃣
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
3️⃣
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
4️⃣
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
我们接下来着重看下,addObserver源码,看我们的观察者究竟是如何感知到声明周期的
1️⃣:首先会设置一个初始化状态initialState,其值取决于mState的状态,mState就是当前组件的状态,如果不是销毁状态,那么就是初始化状态,最终会赋值给initialState
2️⃣:这个地方是不很熟悉了,它又去创建了一个ObserverWithState对象,将观察者和观察者所处组件的状态传入,生成一个带状态的观察者,放进一个mObserverMap,跟LiveData注册如出一辙。
private FastSafeIterableMap mObserverMap =
new FastSafeIterableMap<>();
3️⃣:如果已经注册过了,就直接return
4️⃣:核心代码
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
1️⃣
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
2️⃣
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry newest = mObserverMap.newest();
3️⃣
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
在sync方法中,就涉及到了生命周期的同步和对齐
1️⃣:进入while循环
2️⃣:mState代表当前组件的生命周期,要么是DESTROYED,要么是INITIALIZED,现在在前台肯定就是INITIALIZED
public enum State {
/**
0
*/
DESTROYED,
/**
1
*/
INITIALIZED,
/**
2
*/
CREATED,
/**
3
*/
STARTED,
/**
4
*/
RESUMED;
/**
* Compares if this State is greater or equal to the given {@code state}.
*
* @param state State to compare with
* @return true if this State is greater or equal to the given {@code state}
*/
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
然后会跟mObserverMap中观察者做对比,因为一开始在创建ObserverWithState对象的时候,传入的State就是INITIALIZED,所以 mObserverMap.eldest().getValue().mState == INITIALIZED
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
//看到了吗
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
这个时候,组件的生命周期发生变化,mState从INITIALIZED变为CREATED,这个时候mState比INITIALIZED大,就进入3️⃣
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
final Event event = Event.upFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
3️⃣:forwardPass,其实就是将mObserverMap所有观察者的生命周期同步到与组件一致,调用了观察者的dispatchEvent
在dispatchEvent方法中,我们看到了LifecycleEventObserver的onStateChanged方法被调用,所以我们应该知道为什么onStateChanged会被调用多次了?就是因为LifeCycle生命周期的同步导致的
看上面这张图,应该也就明白了。
当然,我们这里也只是看到了生命周期的同步跟回调,我在添加观察者的时候,我只是做了状态的初始化,那么后续的触发点在哪呢?
看到下面这张图就能明白了!
在FragmentActivity中,LifeCycleRegistry在每个生命周期回调的时候,都调用了handleLifecycleEvent,在handleLifecycleEvent方法中,其实就拿到了当前组件的生命周期,然后给mState赋值,同时调用了sync同步方法进行生命周期对齐
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
像现在所有的Activity都是继承自AppcompatActivity,如果像之前的继承自Activity,如果想要观察者能够感知当前组件的生命周期,就需要实现LifecycleOwner,自己创建一个LifecycleRegistry对象
public class MainActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
MainActivity.this.getLifecycle().addObserver(new MyLifeCycle());
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
@Override
protected void onResume() {
super.onResume();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
@Override
protected void onStart() {
super.onStart();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
}
这样在添加观察者的时候,获取到的Lifecycle对象就是mRegistry,而且在不同的生命周期中,mRegistry都调用了handleLifecycleEvent方法,因此MyLifeCycle同样能够感知Activity的生命周期变化。
作者:想要成为专家的Lay
链接:https://juejin.cn/post/7105367601517166623
更多Android资料可点击下方卡片~