一、Lifecycle & LifecyclRegistry
1. Lifecycler
Lifecycle 是一個抽象類,它的結構很簡單:
- 一系列生命周期事件的枚舉定義:
Event。ON_CREATE...ON_DESTROY,ON_ANY - 一系列當前所處狀態(tài)的定義:
State。DESTROYED,INITIALIZED,CREATED,STARTED,RESUMED。 - 添加、移除觀察者的
addObserver和removeObserver方法
上面的前兩點其實是有關聯性的,是由 事件的變化 驅動 狀態(tài)的變化。它們之間的關系如下圖所示:
image.png
我們來看看系統(tǒng)源碼中是如何表現上面關系的:
INITIALIZED 是一個初態(tài),因此在 Lificycle 的唯一子類 LifecycleRegistry 的構造函數中就將 Lifecycle 的初始狀態(tài)設置為 INITIALIZED:
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
方法 RegistryLifecycle.handleLifecycleEvent(Lifecycle.Event) 是統(tǒng)一接收 Event 并將 State 狀態(tài)流轉到相應值的地方。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
我們再看 getStateAfter 方法,其中寫死了上圖中狀態(tài)流轉的對應關系:
static State getStateAfter(Event event) {
switch (event) {
case ON_CREATE:
case ON_STOP:
return CREATED;
case ON_START:
case ON_PAUSE:
return STARTED;
case ON_RESUME:
return RESUMED;
case ON_DESTROY:
return DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException("Unexpected event value " + event);
}
而調用 handleLifecycleEvent 的地方也是 Fragment/Activity 生命周期回調的地方,這樣就把生命周期回調 → Event → State 綁定了起來:

-
Event.ON_CREATE的發(fā)射是在生命周期回調onCreate之后,但是Event.ON_DESTROY的發(fā)射是在生命周期回調onDestroy之前。事實上,所有的創(chuàng)建事件都在生命周期回調之后,所有的銷毀事件都在生命周期回調之前。
// androidx.fragment.app.Fragment
void performCreate(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
// 標記當前的生命周期狀態(tài)
mState = CREATED;
mCalled = false;
mSavedStateRegistryController.performRestore(savedInstanceState);
// 生命周期回調
onCreate(savedInstanceState);
mIsCreated = true;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onCreate()");
}
// 發(fā)射 lifecycle 事件,更新 lifecycle 狀態(tài)
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performDestroy() {
mChildFragmentManager.dispatchDestroy();
// 發(fā)射 lifecycle 事件,更新 lifecycle 狀態(tài)
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
mState = ATTACHED;
mCalled = false;
mIsCreated = false;
// 生命周期回調
onDestroy();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroy()");
}
}
- 還有個值得注意的地方就是對
Event.ON_STOP的處理。在上面的調用圖中我們可以看到,在onSaveInstanceState和onStop時都派發(fā)了Event.ON_STOP事件,且將狀態(tài)置為了CREATED。這是因為,在onSaveInstanceState后,其實不應該再更新界面了,此時就先派發(fā)Event.ON_STOP使其狀態(tài)為CREATED,阻止ViewModel更新 UI。同時onStop時也需要派發(fā),因為當Activity銷毀時,不一定調用onSaveInstanceState。
2. LifecycleRegistry
LifecycleRegistry 是 Lifecycle 的唯一實現類,負責管理 LifecycleOwner 的當前狀態(tài),及接收 Lifecycle 事件后狀態(tài)的流轉,負責添加移除觀察者 LifecycleObserver,并向觀察者通知 LifecycleOwner 當前的狀態(tài)。主要實現了以下的邏輯:
addObserver添加觀察者時,當前的LifecycleOwner處于什么狀態(tài),觀察者將一次性收到這個狀態(tài)前的所有事件。比如,在onPause時調用addObserver,由于此時LifecyclerOwner(也就是Activity) 處于STARTED狀態(tài),因此觀察者將一次性依次收到ON_CREATE和ON_START兩個事件。我們在實現觀察者時,使用了
@OnLifecycleEvent注解向LifecycleRegistery表示我們關心的事件。其實LifecycleRegistry還為我們每個觀察者綁定了狀態(tài)以確保一種有序性:在任意時刻,后添加的觀察者狀態(tài) <= 先添加的觀察者狀態(tài)。也就是,先添加的觀察者會先收到最新狀態(tài)。當然,最終的穩(wěn)態(tài)一定是所有觀察者的狀態(tài)都一致,但是在給每個觀察者派發(fā)事件的過程中,可能會出現各個觀察者狀態(tài)不一致的情況,LifecycleRegistry會保證上面所說的有序性。
2.1 LifecycleRegistry 的 handleLifecycleEvent 方法 & markState() 方法
看下 handleLifecycleEvent 的源碼:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
// markState 被 @Deprecated 了,使用 setCurrentState
public void setCurrentState(@NonNull State state) {
moveToState(state);
}
可以看到,handleLifecycleRegistry 只是多了一步 getStateAfter 方法,根據 (1),這個方法只是根據一個固定的「事件 —— 狀態(tài)」流轉表來獲取當前應該傳入給 moveToState 的狀態(tài)值。
由于 Activity 和 Fragment 有固定的「事件 —— 狀態(tài)」流轉表,因此在 Activity 和 Fragment 的生命周期方法中,源碼使用 handleLifecycleRegistry()。但是當我們自定義了一個 LifecycleOwner 的時候,可能「事件 —— 狀態(tài)」并不需要那么齊全,這時我們只需要在合適的方法中調用 markState() 就可以了。
二、LifecycleOwner
LifecycleOwner 是一個接口,只有唯一的方法 getLifecycle()。它的典型使用方法就是,一個具有生命周期的類,實現該接口,返回該類對應的 Lifecycle 類(最好用現成的 LifecycleRegistry)。然后在該類(比如 Activity 和 Fragment)的生命周期方法中,調用的 LifecycleRegistry.handleLifecycleEvent 方法,來驅動 Lifecycle 狀態(tài)的改變,同時下發(fā)相應事件。在正常的實踐中,LifecycleOwner 是跟 LifecycleRegistry 一起使用的:
class MyActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.markState(Lifecycle.State.CREATED)
}
public override fun onStart() {
super.onStart()
lifecycleRegistry.markState(Lifecycle.State.STARTED)
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
三、生命周期事件如何在 Activity 和 Fragment 中分發(fā)的?
上一節(jié)我們說到,生命周期事件的分發(fā)是 LifecycleOwner 和 LifecycleRegistry 配合一起的作用,我們來看看常用的 AppCompatActivity。它繼承自 FragmentActivity,在這個類里我們就發(fā)現了下面的代碼:
/**
* A {@link Lifecycle} that is exactly nested outside of when the FragmentController
* has its state changed, providing the proper nesting of Lifecycle callbacks
* <p>
* TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
*/
final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);
不要誤以為 mFragmentLifecycleRegistry 就是 Activity 所對應的 LifecycleRegistry。它雖然在 Activity 的各個生命周期方法中都有調用 handleLifecycleEvent 方法,但是真正使用它的地方是 FragmentActivity 的內部類 HostCallbacks 中。

而
HostCallbacks 的實例作為參數傳入了 FragmentController 中:
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
這里的 mFragments 其實就是一個代理(可以看 ViewModel 的重建恢復原理#番外),它將 Fragment 所關心的 Activity 的事件等通知給 HostCallbacks 所持有的 FragmentManager,包括 Activity 的生命周期。這樣 Activity 的生命周期就傳給了 Fragment。
所以 mFragmentLifecycleRegistry 只是 Activity 將生命周期事件通知給 Fragment 的橋梁。
FragmentActivity 真正的 LifecycleRegistry 應該是通過 getLifecycle() 方法所返回的。jojo
Q: 但是并沒有傳給 Activity 作為 LifecycleOwner 所對應的 LifecycleRegistry。那么 Activity 的 LifecycleRegistry 是在哪里呢?
我們再往父類看 ComponentActivity。在這里我們找到了:
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
ReportFragment.injectIfNeededIn(this);
...
}
關鍵點就在這個 ReportFragment 中。我們注意到 ReportFragment.dispatch 中獲取到了 Activity 的 Lifecycle,并調用了 dispatchLifecycleEvent 方法從而將生命周期事件通知到了 Activity 的 Lifecycle:
// ReportFragment
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
我們再看 ReportFragment.injectIfNeededIn 方法:
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
可以注意到:
- 對于 SDK API ≥ 29 的系統(tǒng),通過直接向
Activity注冊LifecycleCallbacks回調來將生命周期事件通知給LifecycleRegistry。LifecycleCallbacks中的每一個回調都會調用上面的dispatch方法。 - 對于 SDK API < 29 的系統(tǒng),則將該
ReportFragment添加到Activity的FragmentManager中。這樣就可以在ReportFragment自己的生命周期回調中調用dispatch方法。
四、我們使用注解的 Observer 是如何收到生命周期事件的?
注解生成的類
要理解這一節(jié)的內容,最好能夠理解注解處理器的使用。我們知道 APT 在掃描被注解的類后,會調用相應的 processor 來處理這個類,如果有必要,可能會根據這個類的信息來生成一個新的中間類。這個新的中間類就會有很多模板寫法(因此才能夠被生成)。我們來看一個使用注解的類:
static class BoundLocationListener implements LifecycleObserver {
private final Context mContext;
private LocationManager mLocationManager;
private final LocationListener mListener;
public BoundLocationListener(LifecycleOwner lifecycleOwner,
LocationListener listener, Context context) {
mContext = context;
mListener = listener;
lifecycleOwner.getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onLifecycleEvent(LifecycleOwner owner, Lifecycle.Event event) {
Log.d("jojo", "onLifecycleEvent " + owner.getLifecycle().getCurrentState() + ", event " + event);
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void addLocationListener() {
// Note: Use the Fused Location Provider from Google Play Services instead.
// https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi
mLocationManager =
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener);
Log.d("BoundLocationMgr", "Listener added");
// Force an update with the last location, if available.
Location lastLocation = mLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
if (lastLocation != null) {
mListener.onLocationChanged(lastLocation);
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void removeLocationListener() {
if (mLocationManager == null) {
return;
}
mLocationManager.removeUpdates(mListener);
mLocationManager = null;
Log.d("BoundLocationMgr", "Listener removed");
}
}
上面的 BoundLocationListener 類拋開業(yè)務邏輯代碼,其實非常簡單:它繼承自 LifecycleObserver,其中的兩個方法 addLocationListener 和 removeLocationListener 分別被 @OnLifecycleEvent 注解了不同的生命周期。
我們再來看看 BoundLocationListener 被 processor 處理后所生成的中間類:
public class BoundLocationManager_BoundLocationListener_LifecycleAdapter implements GeneratedAdapter {
final BoundLocationManager.BoundLocationListener mReceiver;
BoundLocationManager_BoundLocationListener_LifecycleAdapter(BoundLocationManager.BoundLocationListener receiver) {
this.mReceiver = receiver;
}
@Override
public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
MethodCallsLogger logger) {
boolean hasLogger = logger != null;
if (onAny) {
if (!hasLogger || logger.approveCall("onLifecycleEvent", 4)) {
mReceiver.onLifecycleEvent(owner,event);
}
return;
}
if (event == Lifecycle.Event.ON_RESUME) {
if (!hasLogger || logger.approveCall("addLocationListener", 1)) {
mReceiver.addLocationListener();
}
return;
}
if (event == Lifecycle.Event.ON_PAUSE) {
if (!hasLogger || logger.approveCall("removeLocationListener", 1)) {
mReceiver.removeLocationListener();
}
return;
}
}
}
- 首先從類名上就看得出是由模板拼接出來的,這是方便我們后面說的
Lifecycling通過反射找到該類。 - 它實現了一個統(tǒng)一的接口
GeneratedAdapter,其中只有一個方法callMethods。統(tǒng)一的接口方便Lifecycling統(tǒng)一的管理,因為對于Lifecycling來說,這些生成類都是GeneratedAdapter而已。 - 該類持有
BoundLocationListener的實例,并且在callMethods方法中,通過條件判斷生命周期事件來調用BoundLocationListener的不同方法。
管理注解生成類
分析完注解中間產物類,我們有一個疑問:它是在哪里被初始化,又是在哪里被管理的呢?
我們來看 Observer 被加載到哪里去了。我們知道添加觀察者、移除觀察者的地方是在 LifecycleRegistry 里,在 addObserver 方法中,將傳入進來的 LifecycleObserver 包裝成了 ObserverWithState。我們來看看 ObserverWithState:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
// 這里將 observer 又包裝了一遍
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
Lifecycling 類是我們寫注解時常使用的那種中間 Helper 類,一般來說,它會通過反射等手段來找到我們前面所說的中間產物類(例子中的 BoundLocationManager_BoundLocationListener_LifecycleAdapter 類),管理它的實例、生命周期、方法調用等,并將被注解的業(yè)務類與中間產物類綁定起來。
Lifecycling 的代碼邏輯就比較多了,而且都是用的 Java 反射的特性,我們就不再詳細講解。只說說 lifecycleEventObserver 方法。它會根據我們傳入的 observer 的 Class,然后根據 APT processor 中一樣的規(guī)則來生成中間產物類的類名,然后通過反射得到類的構造函數 Constructor 類,并將其存入到緩存中(方便下次使用時不再反射去找)。最后調用該構造函數,在本例中就是調用 BoundLocationManager_BoundLocationListener_LifecycleAdapter(BoundLocationManager.BoundLocationListener receiver),并返回。返回后就是 ObserverWithState.mLifecycleObserver。當 LifecycleRegistry 分發(fā)事件時,最后會調用到 ObserverWithState.dispatchEvent -> mLifecycleObserver.onStateChanged -> ... -> BoundLocationManager_BoundLocationListener_LifecycleAdapter.callMethods。
LiveData
我們知道 LiveData 也是具有生命周期感知能力的,它與 Lifecycle 綁定,只有當生命周期為 STARTED 或 RESUMED 時,它才會向觀察者發(fā)射數據。同時,在生命周期為 DESTROYED 時,LiveData 也能夠自己釋放。
要實現上面的能力,LiveData 就需要自己既是數據的發(fā)射者,又是生命周期事件的觀察者。數據觀察者通過 observe(LifecycleOwner, Observer) 方法來將自己與 LiveData 綁定,同時為 LiveData 注入 LifecycleOwner,這樣就使 LiveData 觀察生命周期事件成為了可能。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
// 如果 Lifecycle 處于 DESTROYED 狀態(tài),那么就不會往觀察者發(fā)射數據
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 將 owner 和 observer 一起封裝為 LifecycleBoundObserver。
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;
}
// 將 LifecycleBoundObserver 作為觀察者添加進 Lifecycle。
// 這樣,當有生命周期事件時,會調用 LifecycleBoundObserver 的 onStateChange
owner.getLifecycle().addObserver(wrapper);
}
從上面我們可以看到,LiveData 自身其實只是一個管理類。它通過操作 LifecycleBoundObserver 來將 Lifecycle 和 Observer 關聯起來。我們來看下 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) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
對于 Lifecycle 來說,上面的類其實是 LifecycleEventObserver,當 Lifecycle 的生命周期事件需要下發(fā)時,它會調用 LifecycleEventObserver.onStateChanged,在這個方法中我們會看到,如果當前生命周期事件是 DESTROYED,那么會調用 removeObserver 將觀察者從 Lifecycle 中移除掉。否則判斷生命周期是否 ≥ STARTED,如果是的話,則將 LifecycleBoundObserver 的狀態(tài)置為 active,并向開發(fā)者回調 onActive 方法,否則置為 inactive 狀態(tài),并向開發(fā)者回調 onInactive 方法。
LiveData 下發(fā)初值
當 LifecycleBoundObserver 變?yōu)?active 狀態(tài)時,馬上調用 dispatchingValue 下發(fā)當前值。因此 LiveData 的這個行為有點類比于 RxJava 的 BehaviorSubject。這個技術實現的關鍵點在于 considerNotify 函數:
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);
}
上面的 observer.mLastVersion >= mVersion 決定了的一系列關鍵行為。mVersion 初值為 -1,在 LiveData 每次更新值后,mVersion 都會自增 1。
- 當
LiveData中已經有值,此時有一個新的觀察者observer訂閱LiveData。由于observer.mLastVersion的初值為-1,因此上面條件不成立,LiveData向新觀察者observer下發(fā)一次當前值。 - 上面的情況還適合應用因配置改變而導致
Activity或Fragment重建。由于LiveData配合使用在ViewModel中,因此重建后Activity或Fragment中的觀察者對于ViewModel中的LiveData來說依然是新的觀察者。 - 如果觀察者不被重建,則
LiveData從inactive變?yōu)?active時,且LiveData在inactive時更新過數據,上面條件不成立,觀察者還是會收到LiveData最新的數據。反之,LiveData在inactive時沒有更新過數據,則觀察者不會收到LiveData最近一次的數據。
LiveData 更新值
我們來看看 LiveData.setValue:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
實現上一小節(jié)中的關鍵點就在于 setValue 時,將 mVersion 自增 1 來更新版本號。
