Jetpack Compose 中的生命周期 Android Jetpack 的一部分。
生命周期感知型组件可执行操作来响应宿主 activity 的生命周期状态的变化。androidx.lifecycle.compose 制品提供专用 API,可在资源离开屏幕或应用进入后台时自动清理资源。
主要 API 包括:
- 当前
Lifecycle.State的流程。 LifecycleEffects,可让您根据特定的Lifecycle.Event运行代码块。
这些集成提供了便捷的钩子,用于管理 Compose 层次结构中的生命周期。本文档简要介绍了如何在应用中使用它们。
使用数据流收集生命周期状态
Lifecycle 公开了一个 currentStateFlow 属性,该属性以 Kotlin StateFlow 的形式提供当前的 Lifecycle.State。您可以将此 Flow 收集为 State。这样,应用便可以在组合期间读取生命周期的变化。
val lifecycleOwner = LocalLifecycleOwner.current
val stateFlow = lifecycleOwner.lifecycle.currentStateFlow
…
val currentLifecycleState by stateFlow.collectAsState()
可以使用 lifecycle-common 模块访问上述示例。currentStateAsState() 方法可在 lifecycle-runtime-compose 模块中使用,让您只需一行代码即可轻松读取当前的生命周期状态。以下示例对此进行了演示:
val lifecycleOwner = LocalLifecycleOwner.current
val currentLifecycleState = lifecycleOwner.lifecycle.currentStateAsState()
在生命周期事件发生时运行代码
您可以使用特定效应内联声明生命周期逻辑,而无需创建实现 DefaultLifecycleObserver 的单独类并手动将其添加到生命周期中。借助 LifecycleEffects,您可以在组合内直接发生特定 Lifecycle.Event 时运行某个块。
LifecycleEventEffect
使用 LifecycleEventEffect 在发生特定事件时运行一段代码。这种方式最适合一次性事件,例如日志记录或分析,不需要成功或立即获得结果。
@Composable
fun AnalyticsTracker(screenName: String) {
// Log an event when the app receives ON_RESUME (e.g. comes to foreground)
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
Analytics.logView(screenName)
}
}
LifecycleStartEffect
对于需要在应用启动(可见)时运行并在应用停止(在后台)时清理的配对启动/停止操作,请使用 LifecycleStartEffect。
与其他 Compose 效应(如 LaunchedEffect)类似,LifecycleStartEffect 接受键。当键发生变化时,系统会再次触发该代码块运行。
当 Lifecycle.Event.ON_STOP 事件发生或效应退出组合时,它会执行 onStopOrDispose 代码块,以清理启动代码块中的任何工作。
@Composable
fun LocationMonitor(locationManager: LocationManager) {
// Starts monitoring when ON_START is dispatched
// Stops monitoring when ON_STOP is dispatched
// (or the composable leaves the screen)
LifecycleStartEffect(locationManager) {
val listener = LocationListener { location ->
/* update UI */
}
locationManager.requestLocationUpdates(listener)
// The cleanup block automatically runs on ON_STOP or on disposal
onStopOrDispose {
locationManager.removeUpdates(listener)
}
}
}
如需了解其他类型的附带效应,请参阅 Compose 中的附带效应。
LifecycleResumeEffect
LifecycleResumeEffect 的工作方式与 LifecycleStartEffect 相同,但它与 Lifecycle.Event.ON_RESUME 事件相关联。它还提供了一个 onPauseOrDispose 区块,用于在调度 ON_PAUSE 或可组合项离开屏幕时执行清理操作。
此 API 适用于仅在用户与应用互动时需要处于活动状态的资源,例如相机或动画。
@Composable
fun CameraPreview(cameraController: CameraController) {
LifecycleResumeEffect(cameraController) {
cameraController.startPreview()
onPauseOrDispose {
cameraController.stopPreview()
}
}
}
访问 LifecycleOwner
在 Compose 中,LifecycleOwner 通过名为 LocalLifecycleOwner 的 CompositionLocal 隐式提供。默认情况下,组合层次结构的根宿主会提供此所有者。
val lifecycleOwner = LocalLifecycleOwner.current
对于许多应用,检查此默认所有者或将其传递给生命周期感知效应就足够了。不过,对于自定义导航或复杂布局,您可能需要创建自己的 LifecycleOwner,以便将生命周期状态限定为界面的特定部分。例如,导航库(如 Navigation 3)会自动执行此操作,以便为每个单独的屏幕提供自己的生命周期。
创建自定义 LifecycleOwner
借助 rememberLifecycleOwner() API,您可以创建并记住自定义 LifecycleOwner。这对于 HorizontalPager 等组件尤其有用,您可能希望只有可见的已稳定页面为 RESUMED,而相邻的屏幕外页面则设置为 maxState 的 STARTED。
val pagerState = rememberPagerState(pageCount = { 10 })
HorizontalPager(state = pagerState) { pageNum ->
val pageLifecycleOwner = rememberLifecycleOwner(
maxState = if (pagerState.settledPage == pageNum) {
Lifecycle.State.RESUMED
} else {
Lifecycle.State.STARTED
}
)
CompositionLocalProvider(LocalLifecycleOwner provides pageLifecycleOwner) {
// Your pages here. Their lifecycle-aware components respect the
// custom maxState defined above.
}
}
如需详细了解 CompositionLocal,请参阅使用 CompositionLocal 将数据的作用域限定在局部。
有关生命周期感知型组件的最佳实践
- 使界面控制器尽可能保持精简。它们不应试图获取自己的数据,而应使用
ViewModel执行此操作,同时应观测StateFlow对象以在界面中体现相应变化。 - 设法编写数据驱动型界面,在此类界面中,界面控制器负责随着数据的更改更新界面,或者向
ViewModel通知用户的操作。 - 将数据逻辑放在
ViewModel类中。ViewModel应充当界面控制器与应用其余部分之间的连接器。不过要注意,ViewModel不负责获取数据(例如,从网络获取)。但是,ViewModel应调用相应的组件来提取数据,然后将结果提供给界面控制器。 - 使用 Kotlin 协程管理长时间运行的任务和其他可以异步运行的操作。
- 将启动/停止逻辑保留在实际需要它的可组合函数中。这样一来,如果从屏幕中移除该特定界面元素(例如,在导航图中或当可见性为条件性时),系统会自动移除相应逻辑。
- 使用
collectAsStateWithLifecycle作为数据。请勿根据生命周期事件手动开始或停止Flow收集。请改用collectAsStateWithLifecycle将数据流高效转换为界面状态。这样可以节省电量和资源,因为当应用在后台运行时,Flow会暂停。
如需详细了解 Flows,请参阅其他受支持的状态类型。
生命周期感知型组件的用例
生命周期感知型组件可使您在各种情况下更轻松地管理生命周期。下面是几个例子:
- 在粗粒度和细粒度位置信息更新之间切换。使用
LifecycleStartEffect可在应用可见 (ON_START) 时启用细粒度位置信息更新,并在应用位于后台 (ON_STOP) 时自动清理监听器或切换到粗粒度更新。 - 停止和开始视频缓冲。使用
LifecycleResumeEffect可将实际视频播放延迟到应用完全处于前台并可互动 (ON_RESUME) 时,并确保当应用转到后台 (ON_PAUSE) 时,播放会暂停并释放资源。 - 开始和停止网络串流。使用
collectAsStateWithLifecycle观察连续的数据流(例如来自网络套接字的 Kotlin Flow)。这样一来,您便可在应用位于前台时进行实时更新,并在应用进入后台时自动取消收集。 - 暂停和恢复繁重任务。使用
LifecycleResumeEffect可在应用位于后台时暂停繁重的视觉更新,并在应用位于前台后恢复这些更新。
安全地处理 ON_STOP 事件
Compose 旨在安全地处理 ON_STOP 事件。
- 状态安全:您可以随时更新
MutableState(例如,使用uiState.value = ...),即使应用在后台运行也是如此。 Compose 会等待应用可见,然后才渲染更改。 - 自动清理:借助
LifecycleStartEffect等效应,清理块 (onStopOrDispose) 会在生命周期移至STOPPED时准确运行。这样可防止应用在后台运行时占用大量资源(例如相机或位置信息)。
如需详细了解 MutableState,请参阅状态和 Jetpack Compose。
其他资源
如需详细了解如何使用生命周期感知型组件处理生命周期,请参阅以下资源。
查看内容
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- LiveData 概览
- 将 Kotlin 协程与生命周期感知型组件一起使用
- ViewModel 的已保存状态模块