Android Jetpack LiveData 与 Lifecycle 源码深度解析
Jetpack 组件是 Google 力推的架构模式,能够帮助我们快速构建项目。在 Jetpack 丰富的组件当中,生命周期几乎是贯穿全部,万物皆始于声明周期。从本章开始,深入 Jetpack 核心组件源码。
1. LiveData 源码分析
看到 LiveData 这个名字,第一感觉这是一个数据类,其实不是的。LiveData 能够持有任意一种数据并且能够对这个数据进行观察。在 LiveData 之前,我们通过回调的方式获取网络请求返回的数据,从而进行 View 的数据展示,MVP 架构就是采用这种原理。可为什么 MVP 越来越不受待见?是因为大量的数据接口编写,以及可能出现的回调地狱(这也是其中一个原因,不是全部)。
LiveData 采用的观察者模式,能够感知数据的变化,从而通过数据驱动 UI,这也是 MVVM 架构的核心思想,其实你也可以看做是接口的回调。除此之外,LiveData 具备生命周期感知能力,只有在 Activity 或者 Fragment 处于活跃状态时,才会回调数据,能够避免内存泄漏。
1.1 MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
public MutableLiveData(T value) {
super(value);
}
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 方法。
1.1.1 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<Map.Entry<Observer<? super T>, 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) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
1️⃣ 2️⃣ 3️⃣:这个我们放在后面说,很重要的一个版本号机制。
4️⃣:最终我们可以看到,considerNotify 方法中调用了观察者的 onChanged 方法,并把 mData 传了进去,mData 之前我们说过,其实就是我们传入的数据,也是 LiveData 真正的数据持有者。
1.1.2 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) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
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;
}
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;
}
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<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
其中调用 putIfAbsent 方法,主要就是为了判断当前观察者是否已经被注册过了,如果已经存在这个 key,那么返回的就不为空。
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry<K, V> 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 {
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
所以,我们可以这么理解,只要我们实现了这个接口,并且作为观察者交给组件,就能感知组件的生命周期,我们可以尝试一下。
1.1.3 自动管理生命周期
首先我们创建一个观察者对象,实现 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 或者 onDestroy 中去做相关的处理逻辑。
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) {
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();
}
}
在这个方法中,就能回调组件的生命周期。
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 方法,这里就是产生粘性事件的原因所在。
1.1.4 粘性事件
我们来看个一个场景。
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) {
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;
}
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 了。
1.1.5 版本号机制
我们看一下这个版本号,首先 mLastVersion 是 ObserverWrapper 的成员变量,默认值是 -1;mVersion 是 LiveData 的一个成员变量,如果是调用的空参构造方法,默认值也是 -1,如果非空参构造方法,那么就就会将版本号+1,而且会把初始值赋值给 mData,我们使用时一般都是采用空参构造方法。
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;
}
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 种:
- postValue / setValue
- 当组件的生命周期发生改变或者我们第一次注册观察者时
1.2 LiveData 事件总线
像实际的开发中,我们使用 LiveData 不仅仅局限于当前页面的数据展示,包括跨组件、跨页面的通信,同样会使用到 LiveData,那么通过 LiveData 来实现一个事件总线,熟悉使用 EventBus 的伙伴应该都清楚。
public class LiveDataBus {
private Map<String, MutableLiveData<Object>> 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 <T> MutableLiveData<T> with(String key,Class<T> clazz){
if(!map.containsKey(key)){
map.put(key, new MutableLiveData<>());
}
return (MutableLiveData<T>) map.get(key);
}
}
with 方法用于创建新的 LiveData 对象或者直接返回已有的 LiveData 对象。
MutableLiveData<String> liveData1 = LiveDataBus.getInstance().with("key", String.class);
liveData1.postValue("1234567");
记不记得之前的小结中,提到的粘性事件,其实官方的 LiveData 就是存在这个粘性事件的,所以在实际的开发中,这种跳转页面传递参数没有问题,但是如果某些场景就不能使用这种粘性事件,那么官方的 LiveData 就不能使用了,需要我们自己去处理粘性事件。
前面提到过,粘性事件产生的主要原因就是,在注册观察者的时候,就会导致数据的回调,那么我们是不是可以在数据回调之前,就将观察者的版本号修改成与 LiveData 的版本号保持一致,是不就可以。
public class MyLiveData<T> extends MutableLiveData<T> {
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) {
try {
hookObserver(observer);
}catch (Exception e){
}
}
private void hookObserver(Observer<? super T> observer) {
Class<LiveData> aClass = LiveData.class;
try {
Field mObserversFiled = aClass.getDeclaredField("mObservers");
mObserversFiled.setAccessible(true);
Object mObservers = mObserversFiled.get(this);
Method getMethod = mObservers.getClass().getDeclaredMethod(,Object.class);
getMethod.setAccessible();
;
getMethod.invoke(mObservers,observer);
(entry != && entry Map.Entry){
wrapper = ((Map.Entry<?, ?>) entry).getValue();
}
(wrapper == ){
Log.e(,);
}
wrapper.getClass().getSuperclass().getDeclaredField();
mLastVersionFiled.setAccessible();
aClass.getDeclaredField();
mVersionFiled.setAccessible();
mVersionFiled.get();
mLastVersionFiled.set(wrapper,mVersion);
} (Exception e){
Log.e(,+e);
}
}
}
这里是重写了 LiveData,并且传入了一个参数 isSticky 来确认是否需要粘性事件,如果需要粘性事件,那么就直接走正常的 LiveData 的注册逻辑;
如果不需要粘性事件,那么其实就是通过 hook 的方式来修改观察者 observer 的版本号 mLastVersion 等于 LiveData 的版本号 mVersion,基本的反射操作,其实通过前面的源码讲解,这块就非常简单了。
大家其实没必要担心 hook 之后影响当前组件的数据发送,因为每次 post 或者 set 都会增加 mVersion 的版本号,肯定是能够回调 onChanged 方法!
2. LifeCycle 源码分析
其实在 LiveData 的源码中,我们已经接触到了 LifeCycle,其实 LifeCycle 的出现,真的是极大地解放了我们的双手,能够动态感知组件的生命周期,那么 LifeCycle 是怎么做到的呢?
2.1 getLifecycle
owner.getLifecycle().addObserver(wrapper);
我们拿 LiveData 中 observe 方法的最后一行代码入手,首先调用了 getLifecycle 方法。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
LifeCycle 是一个抽象类,获取到的肯定是它的一个子类,我们先从 Activity 组件入手,看看 getLifecycle 拿到的是什么。
public Lifecycle getLifecycle() {
return mFragmentLifecycleRegistry;
}
通过 FragmentActivity 源码中的 getLifecycle 方法我们得知,getLifecycle 拿到的是一个 LifecycleRegistry 对象,它就是 LifeCycle 的一个子类。
其实调用 addObserver,就是调用了 LifecycleRegistry 的 addObserver 方法。
2.2 addObserver
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
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 == ) {
( + statefulObserver.mState);
}
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
targetState = calculateTargetState(observer);
}
(!isReentrance) {
sync();
}
mAddingObserverCounter--;
}
我们接下来着重看下,addObserver 源码,看我们的观察者究竟是如何感知到声明周期的。
1️⃣:首先会设置一个初始化状态 initialState,其值取决于 mState 的状态,mState 就是当前组件的状态,如果不是销毁状态,那么就是初始化状态,最终会赋值给 initialState。
2️⃣:这个地方是不很熟悉了,它又去创建了一个 ObserverWithState 对象,将观察者和观察者所处组件的状态传入,生成一个带状态的观察者,放进一个 mObserverMap,跟 LiveData 注册如出一辙。
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> 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.");
}
while (!isSynced()) {
mNewEventOccurred = false;
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
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 {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
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<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> 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;
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 的生命周期变化。
总结
本文详细剖析了 Android Jetpack 中 LiveData 和 Lifecycle 的核心源码机制。LiveData 通过观察者模式结合生命周期感知能力,有效解决了传统回调方式带来的内存泄漏和数据更新不及时的问题。其内部的版本号机制确保了观察者不会因生命周期状态波动而重复接收数据,同时提供了处理粘性事件的灵活方案。Lifecycle 组件则通过 LifecycleRegistry 实现了组件生命周期状态的统一管理与同步,使得开发者无需手动干预即可自动响应生命周期事件。掌握这些底层原理,有助于在实际开发中更合理地设计架构,提升应用的稳定性和可维护性。