一、Lifecycle & LifecyclRegistry
1. Lifecycler
Lifecycle
是一个抽象类,它的结构很简单:
- 一系列生命周期事件的枚举定义:
Event
。ON_CREATE
...ON_DESTROY
,ON_ANY
- 一系列当前所处状态的定义:
State
。DESTROYED
,INITIALIZED
,CREATED
,STARTED
,RESUMED
。 - 添加、移除观察者的
addObserver
和removeObserver
方法
上面的前两点其实是有关联性的,是由 事件的变化 驱动 状态的变化。它们之间的关系如下图所示:
我们来看看系统源码中是如何表现上面关系的:
INITIALIZED
是一个初态,因此在 Lificycle
的唯一子类 LifecycleRegistry
的构造函数中就将 Lifecycle
的初始状态设置为 INITIALIZED
:
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
方法 RegistryLifecycle.handleLifecycleEvent(Lifecycle.Event)
是统一接收 Event
并将 State
状态流转到相应值的地方。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
我们再看 getStateAfter
方法,其中写死了上图中状态流转的对应关系:
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
的发射是在生命周期回调onCreate
之后,但是Event.ON_DESTROY
的发射是在生命周期回调onDestroy
之前。事实上,所有的创建事件都在生命周期回调之后,所有的销毁事件都在生命周期回调之前。
// androidx.fragment.app.Fragment
void performCreate(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
// 标记当前的生命周期状态
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()");
}
// 发射 lifecycle 事件,更新 lifecycle 状态
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performDestroy() {
mChildFragmentManager.dispatchDestroy();
// 发射 lifecycle 事件,更新 lifecycle 状态
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
时都派发了Event.ON_STOP
事件,且将状态置为了CREATED
。这是因为,在onSaveInstanceState
后,其实不应该再更新界面了,此时就先派发Event.ON_STOP
使其状态为CREATED
,阻止ViewModel
更新 UI。同时onStop
时也需要派发,因为当Activity
销毁时,不一定调用onSaveInstanceState
。
2. LifecycleRegistry
LifecycleRegistry
是 Lifecycle
的唯一实现类,负责管理 LifecycleOwner
的当前状态,及接收 Lifecycle 事件后状态的流转,负责添加移除观察者 LifecycleObserver
,并向观察者通知 LifecycleOwner
当前的状态。主要实现了以下的逻辑:
addObserver
添加观察者时,当前的LifecycleOwner
处于什么状态,观察者将一次性收到这个状态前的所有事件。比如,在onPause
时调用addObserver
,由于此时LifecyclerOwner
(也就是Activity
) 处于STARTED
状态,因此观察者将一次性依次收到ON_CREATE
和ON_START
两个事件。我们在实现观察者时,使用了
@OnLifecycleEvent
注解向LifecycleRegistery
表示我们关心的事件。其实LifecycleRegistry
还为我们每个观察者绑定了状态以确保一种有序性:在任意时刻,后添加的观察者状态 <= 先添加的观察者状态。也就是,先添加的观察者会先收到最新状态。当然,最终的稳态一定是所有观察者的状态都一致,但是在给每个观察者派发事件的过程中,可能会出现各个观察者状态不一致的情况,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),这个方法只是根据一个固定的「事件 —— 状态」流转表来获取当前应该传入给 moveToState
的状态值。
由于 Activity
和 Fragment
有固定的「事件 —— 状态」流转表,因此在 Activity
和 Fragment
的生命周期方法中,源码使用 handleLifecycleRegistry()
。但是当我们自定义了一个 LifecycleOwner
的时候,可能「事件 —— 状态」并不需要那么齐全,这时我们只需要在合适的方法中调用 markState()
就可以了。
二、LifecycleOwner
LifecycleOwner
是一个接口,只有唯一的方法 getLifecycle()
。它的典型使用方法就是,一个具有生命周期的类,实现该接口,返回该类对应的 Lifecycle
类(最好用现成的 LifecycleRegistry
)。然后在该类(比如 Activity
和 Fragment
)的生命周期方法中,调用的 LifecycleRegistry.handleLifecycleEvent
方法,来驱动 Lifecycle
状态的改变,同时下发相应事件。在正常的实践中,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 中分发的?
上一节我们说到,生命周期事件的分发是 LifecycleOwner
和 LifecycleRegistry
配合一起的作用,我们来看看常用的 AppCompatActivity
。它继承自 FragmentActivity
,在这个类里我们就发现了下面的代码:
/**
* A {@link Lifecycle} that is exactly nested outside of when the FragmentController
* has its state changed, providing the proper nesting of Lifecycle callbacks
*
* 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 的系统,通过直接向
Activity
注册LifecycleCallbacks
回调来将生命周期事件通知给LifecycleRegistry
。LifecycleCallbacks
中的每一个回调都会调用上面的dispatch
方法。 - 对于 SDK API < 29 的系统,则将该
ReportFragment
添加到Activity
的FragmentManager
中。这样就可以在ReportFragment
自己的生命周期回调中调用dispatch
方法。
四、我们使用注解的 Observer 是如何收到生命周期事件的?
注解生成的类
要理解这一节的内容,最好能够理解注解处理器的使用。我们知道 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
类抛开业务逻辑代码,其实非常简单:它继承自 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
通过反射找到该类。 - 它实现了一个统一的接口
GeneratedAdapter
,其中只有一个方法callMethods
。统一的接口方便Lifecycling
统一的管理,因为对于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
类),管理它的实例、生命周期、方法调用等,并将被注解的业务类与中间产物类绑定起来。
Lifecycling
的代码逻辑就比较多了,而且都是用的 Java 反射的特性,我们就不再详细讲解。只说说 lifecycleEventObserver
方法。它会根据我们传入的 observer
的 Class
,然后根据 APT processor
中一样的规则来生成中间产物类的类名,然后通过反射得到类的构造函数 Constructor
类,并将其存入到缓存中(方便下次使用时不再反射去找)。最后调用该构造函数,在本例中就是调用 BoundLocationManager_BoundLocationListener_LifecycleAdapter(BoundLocationManager.BoundLocationListener receiver)
,并返回。返回后就是 ObserverWithState.mLifecycleObserver
。当 LifecycleRegistry
分发事件时,最后会调用到 ObserverWithState.dispatchEvent
-> mLifecycleObserver.onStateChanged
-> ... -> BoundLocationManager_BoundLocationListener_LifecycleAdapter.callMethods
。
LiveData
我们知道 LiveData
也是具有生命周期感知能力的,它与 Lifecycle
绑定,只有当生命周期为 STARTED
或 RESUMED
时,它才会向观察者发射数据。同时,在生命周期为 DESTROYED
时,LiveData
也能够自己释放。
要实现上面的能力,LiveData
就需要自己既是数据的发射者,又是生命周期事件的观察者。数据观察者通过 observe(LifecycleOwner, Observer)
方法来将自己与 LiveData
绑定,同时为 LiveData
注入 LifecycleOwner
,这样就使 LiveData
观察生命周期事件成为了可能。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
assertMainThread("observe");
// 如果 Lifecycle 处于 DESTROYED 状态,那么就不会往观察者发射数据
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
的生命周期事件需要下发时,它会调用 LifecycleEventObserver.onStateChanged
,在这个方法中我们会看到,如果当前生命周期事件是 DESTROYED
,那么会调用 removeObserver
将观察者从 Lifecycle
中移除掉。否则判断生命周期是否 ≥ STARTED
,如果是的话,则将 LifecycleBoundObserver
的状态置为 active
,并向开发者回调 onActive
方法,否则置为 inactive
状态,并向开发者回调 onInactive
方法。
LiveData 下发初值
当 LifecycleBoundObserver
变为 active
状态时,马上调用 dispatchingValue
下发当前值。因此 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
下发一次当前值。 - 上面的情况还适合应用因配置改变而导致
Activity
或Fragment
重建。由于LiveData
配合使用在ViewModel
中,因此重建后Activity
或Fragment
中的观察者对于ViewModel
中的LiveData
来说依然是新的观察者。 - 如果观察者不被重建,则
LiveData
从inactive
变为active
时,且LiveData
在inactive
时更新过数据,上面条件不成立,观察者还是会收到LiveData
最新的数据。反之,LiveData
在inactive
时没有更新过数据,则观察者不会收到LiveData
最近一次的数据。
LiveData 更新值
我们来看看 LiveData.setValue
:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
实现上一小节中的关键点就在于 setValue
时,将 mVersion
自增 1 来更新版本号。