文章目录
前言
Jetpack Compose 的生命周期与传统的 View 不同,它主要基于 Composition 和 Recomposition 两个阶段来管理 UI 的创建和更新,同时通过一些工具(如 LaunchedEffect、DisposableEffect)来处理生命周期事件。
提示:以下是本篇文章正文内容,下面案例可供参考
1、Compose UI 的生命周期是什么?
Compose 的生命周期围绕以下三个阶段展开:
-
初次 Composition
UI 的首次构建阶段,相当于传统 View 的 onCreate()。 -
Recomposition
当状态发生变化时,Compose 只更新受影响的 UI 部分,类似于传统 View 的 onDraw()。 -
Disposal(销毁)
UI 不再需要时的资源清理阶段,相当于传统 View 的 onDestroy()。
生命周期流转图
Compose 生命周期与传统生命周期的对比
传统 View 生命周期 | Compose 生命周期 |
---|---|
onCreate() | 初次 Composition |
onStart() / onResume() | 通过 LaunchedEffect 初始化资源 |
onPause() / onStop() | 无明确对应,状态由生命周期感知管理 |
onDestroy() | DisposableEffect 的清理回调 |
onDraw() | Recomposition |
2、各阶段详细解析
2.1 初次 Composition:UI 的出生
这是 Compose UI 生命周期中的第一步。
当你第一次调用 @Composable 函数时,Compose 会构建 UI 树并为其分配内存。
这就相当于传统 Android 中的 onCreate(),即 UI 组件的初始化阶段。
关键点:
- Compose 会将 UI 树构建在内存中,并关联 UI 元素和数据源。
- 在这阶段,所有的初始状态都会被设置。
示例代码:
@Composable
fun Greeting(name: String) {
// 使用 `remember` 保存状态,仅在初次 Composition 初始化
val greetingMessage = remember { "Hello, $name!" }
Text(text = greetingMessage)
}
重点解析:
- remember 会记住数据,避免每次 UI 更新时重新初始化。
2.2 Recomposition(UI 更新)
Recomposition 是 Compose 最强大的特性之一。当状态发生变化时,Compose 会高效地更新受影响的 UI 部分,而不是重新创建整个 UI 树。
比如,用户点击按钮或数据源发生变化时,只会重新绘制有变化的部分。
关键点:
- 高效更新:Compose 会精确地追踪状态的变化,仅更新变化的部分,而不是重绘整个屏幕。
- Recomposition 是 按需 触发的,而不是每次都发生,极大提升了性能。
示例代码:
@Composable
fun Counter() {
val count = remember { mutableStateOf(0) }
Column {
Button(onClick = { count.value++ }) {
Text("点击次数: ${count.value}")
}
if (count.value > 5) {
Text("点击超过5次了!")
}
}
}
重点:
当 count.value 发生变化时,只有 Button 和 Text 会重新组合,其他部分保持不变。
2.3 Disposal(资源清理)
Disposal 阶段发生在 UI 组件被销毁时。这时,Compose 会清理相关的资源,释放内存。
这相当于传统 Android 中的 onDestroy(),比如关闭监听器、取消任务或释放占用的资源。
关键点:
- UI 被移除后,相关的资源会被清理。
- 这可以通过 DisposableEffect 等 Compose API 来显式管理。
示例代码:
@Composable
fun DisposableEffectExample() {
DisposableEffect(Unit) {
// 初始化资源
println("资源初始化")
onDispose {
// 清理资源
println("资源销毁")
}
}
}
重点:
onDispose 回调会在 UI 被移除时触发,适合做资源清理工作,如注销监听器、关闭连接等。
2.4 生命周期管理与状态控制
在 Compose 中,状态变化控制着 UI 的构建和更新,所有 UI 组件的变化都可以通过状态的更新来驱动。以下是与生命周期相关的几个关键 API,它们帮助我们更好地管理资源和 UI 更新:
2.4.1 LaunchedEffect(启动协程)
LaunchedEffect 用于启动协程并执行与 UI 生命周期相关的异步任务。协程在 @Composable 函数的初次 Composition 或 key 变化时启动,并在函数销毁时取消。
@Composable
fun TimerExample() {
val time = remember { mutableStateOf(0) }
// 每秒更新一次计时器
LaunchedEffect(Unit) {
while (true) {
kotlinx.coroutines.delay(1000)
time.value++
}
}
Text(text = "计时器: ${time.value} 秒")
}
2.4.2 DisposableEffect(清理资源)
DisposableEffect 用来管理与 UI 绑定的外部资源,确保在组件销毁时清理资源。
示例代码:
@Composable
fun LifecycleAwareComponent() {
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
println("Lifecycle event: $event")
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
2.4.3 SideEffect
在 Recomposition 之后触发副作用,用于通知外部系统。
触发时机:每次 Recomposition 完成时。
示例代码:
@Composable
fun SideEffectExample(counter: Int) {
SideEffect {
println("Recomposition 完成,当前计数: $counter")
}
Text(text = "计数: $counter")
}
- SideEffect 通常用于更新非 Compose 管理的系统状态(如日志或外部变量)。
- 每次 UI 更新后都会触发。
2.4.4 remember(状态记忆)
remember 用于在 Composition 期间保存状态,它避免了在每次 Recomposition 时重建数据,特别适用于在状态不变时保留数据。
示例代码:
@Composable
fun Counter() {
val count = remember { mutableStateOf(0) }
Button(onClick = { count.value++ }) {
Text("点击次数: ${count.value}")
}
}
总结
- Jetpack Compose 的生命周期分为 Composition、Recomposition 和 Disposal。
- 核心工具:
LaunchedEffect:处理异步任务,与 UI 生命周期绑定。
DisposableEffect:管理资源的初始化和清理。
remember 和 mutableStateOf:保存 UI 状态。
SideEffect:处理与外部系统的交互。 - 与传统 View 生命周期相比,Compose 更关注状态变化驱动的重组和资源管理,避免了冗余的生命周期回调。