Tips: 本文基于 lifecycle-2.4.0 分析。截止完成时 Lifecycle 组件最新版本为 2.4.0。
2.4.0 版本变更
- 废弃了
@OnLifecycleEvent
。应改用LifecycleEventObserver
或DefaultLifecycleObserver
- 向
androidx.lifecycle:lifecycle-runtime-ktx
添加了新的协程 API:-
Lifecycle.repeatOnLifecycle
- 当 Lifecycle 至少处于某个状态时,此 API 会在协程中执行代码块。当 Lifecycle 进入和退出目标状态时,该代码块将取消并重新启动; -
Flow.flowWithLifecycle
- 当 Lifecycle 至少处于某个状态时,此 API 会发出来自上游 flow 的值。
-
- 现在,
lifecycle-process
使用androidx.startup
来初始化ProcessLifecycleOwner
。之前此操作是由androidx.lifecycle.ProcessLifecycleOwnerInitializer
完成的。
dependencies {
def lifecycle_version = "2.4.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// ViewModel utilities for Compose
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
今天我们重点来看 androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version
中的内容。
LifecycleOwner LifecycleObserver 和 Lifecycle
Lifecyle 组件拥有三大基石:Lifecycle,LifecycleObserver 以及 LifecycleOwner。
LifecycleObserver 顾名思义代表的是生命周期中的观察者:
public interface LifecycleObserver {
}
LifecycleOwner 则是生命周期的拥有者,在 Android 中 Fragment 和 ComponentActivity 都实现了此接口:
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
最后就是 Lifecycle,每个 LifecycleOwner 都会持有 Lifecycle 对象,通过它我们才可以获得当前的所处的生命周期,增加、删除观察者:
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public abstract State getCurrentState();
}
Lifecycle 类里还定义了两个枚举类 Event
和 State
:
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
}
在 Event 类中提供了 upFrom()
、upTo()
、downFrom()
、downTo()
以及 getTargetState()
方法,分别用来获取当前 State 向前、向后转换所对应的 Event 以及当前 Event 所对应的 State:
@Nullable
public static Event upFrom(@NonNull State state) {
switch (state) {
case INITIALIZED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
default:
return null;
}
}
@Nullable
public static Event upTo(@NonNull State state) {
switch (state) {
case CREATED:
return ON_CREATE;
case STARTED:
return ON_START;
case RESUMED:
return ON_RESUME;
default:
return null;
}
}
@NonNull
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
State 类中提供了 isAtLeast()
方法,用来判断当前 State 是否高于给定的最低 State:
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
整体的 State 与 Event 关系则如图所示: 我们先来看看 Fragment 和 ComponentActivity 中 getLifecycle() 的实现:
LifecycleRegistry mLifecycleRegistry;
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
LifecycleRegistry 是 Lifecycle 的实现类,有一段需要注意的代码是:
@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);
...
// 看这里
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);
}
...
}
- 这段代码表明,即使我们在 State 为 RESUMED 时添加订阅者,该订阅者同样能够接收到完整的 ON_CREATE,ON_START,ON_RESUME 事件流。
在 2.4.0 以前的版本,Lifecycle 可以搭配 OnLifecycleEvent
注解来使用:
public class MLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate() { Log.d(TAG, "onCreate"); }
}
如果是 Java8 的话,可以通过实现 DefaultLifecycleObserver
来使用。而到了 2.4.0 版本后,OnLifecycleEvent
已经被标记废弃,需要替换成实现 DefaultLifecycleObserver
或 LifecycleEventObserver
:
如果同时实现了
DefaultLifecycleObserver
和LifecycleEventObserver
两个接口,那么会先触发DefaultLifecycleObserver
,然后再触发LifecycleEventObserver
。
万事具备,只欠东风了。Lifecyle 如何与组件绑定,从而获取到生命周期的变化的呢? 让我们看看 ComponentActivity 的实现:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ReportFragment.injectIfNeededIn(this)
就是关键所在:
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity);
}
// 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();
}
}
repeatOnLifecycle & flowWithLifecycle
flowWithLifecycle 实际上就是调用 repeatOnLifecycle:
public fun <T> Flow<T>.flowWithLifecycle(
lifecycle: Lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T> = callbackFlow {
lifecycle.repeatOnLifecycle(minActiveState) {
this@flowWithLifecycle.collect {
send(it)
}
}
close()
}
repeatOnLifecycle 实现如下:
public suspend fun Lifecycle.repeatOnLifecycle(
state: Lifecycle.State,
block: suspend CoroutineScope.() -> Unit
) {
require(state !== Lifecycle.State.INITIALIZED) {
"repeatOnLifecycle cannot start work with the INITIALIZED lifecycle state."
}
if (currentState === Lifecycle.State.DESTROYED) {
return
}
// This scope is required to preserve context before we move to Dispatchers.Main
coroutineScope {
withContext(Dispatchers.Main.immediate) {
// Check the current state of the lifecycle as the previous check is not guaranteed
// to be done on the main thread.
if (currentState === Lifecycle.State.DESTROYED) return@withContext
// Instance of the running repeating coroutine
var launchedJob: Job? = null
// Registered observer
var observer: LifecycleEventObserver? = null
try {
// Suspend the coroutine until the lifecycle is destroyed or
// the coroutine is cancelled
suspendCancellableCoroutine<Unit> { cont ->
// Lifecycle observers that executes `block` when the lifecycle reaches certain state, and
// cancels when it falls below that state.
val startWorkEvent = Lifecycle.Event.upTo(state)
val cancelWorkEvent = Lifecycle.Event.downFrom(state)
val mutex = Mutex()
observer = LifecycleEventObserver { _, event ->
if (event == startWorkEvent) {
// Launch the repeating work preserving the calling context
launchedJob = this@coroutineScope.launch {
// Mutex makes invocations run serially,
// coroutineScope ensures all child coroutines finish
mutex.withLock {
coroutineScope {
block()
}
}
}
return@LifecycleEventObserver
}
if (event == cancelWorkEvent) {
launchedJob?.cancel()
launchedJob = null
}
if (event == Lifecycle.Event.ON_DESTROY) {
cont.resume(Unit)
}
}
this@repeatOnLifecycle.addObserver(observer as LifecycleEventObserver)
}
} finally {
launchedJob?.cancel()
observer?.let {
this@repeatOnLifecycle.removeObserver(it)
}
}
}
}
}
ProcessLifecycleOwner
Lifecycle 还提供了一个 ProcessLifecycleOwner 用来获取整个 application 的生命周期,在这个 Lifecycle 中,ON_CREATE 只会在创建时出现一次,并且永远不会出现 ON_DESTROY 事件。ON_START,ON_RESUME 会在第一个 activity 触发时发送;而 ON_PAUSE,ON_STOP 会在最后一个 activity 触发后延迟一小段时间后发出。各位可以思考下这是为什么?愿意很简单,是为了避免因 configerationChanged 导致销毁重建而发出错误的 Event。
那么再有需要监控应用前后台的场景时就可以这么做了:
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Log.e(TAG,"进入前台")
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Log.e(TAG,"进入后台")
}
})