这一节了解一下DisposableEffect,它是一个可组合函数,主要用于在可组合项进入组合时执行初始化操作,并且在可组合项从组合中移除时执行相应的清理操作。其核心目的是管理与可组合项生命周期相关的资源,避免资源泄漏,比如注册和注销监听器、打开和关闭数据库连接等操作都可以借助它来完成。
基本用法:
DisposableEffect 接收一个或多个键(key)以及一个 Lambda 表达式。当可组合项首次组合时,会执行 Lambda 表达式中的代码。该 Lambda 表达式需要返回一个 DisposableEffectScope 类型的对象,其中包含一个 onDispose 方法,这个方法会在可组合项从组合中移除时被调用,用于执行清理操作。
import androidx.compose.runtime.*
import androidx.compose.material3.Text
import android.util.Log@Composable
fun BasicDisposableEffectExample() {DisposableEffect(Unit) {// 初始化操作,例如注册监听器Log.d("DisposableEffect", "可组合项进入组合,执行初始化操作")// 定义清理操作onDispose {Log.d("DisposableEffect", "可组合项从组合中移除,执行清理操作")}}Text("这是一个基本的 DisposableEffect 示例")
}
分析:DisposableEffect 接收 Unit 作为键。当可组合项首次组合时,会打印初始化操作的日志;当可组合项从组合中移除时,会打印清理操作的日志。
import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import android.util.Log@Composable
fun DisposableEffectWithKeyExample() {var counter by remember { mutableStateOf(0) }DisposableEffect(counter) {// 初始化操作Log.d("DisposableEffect", "可组合项进入组合或键变化,当前计数器值: $counter,执行初始化操作")// 定义清理操作onDispose {Log.d("DisposableEffect", "可组合项从组合中移除或键变化,当前计数器值: $counter,执行清理操作")}}Button(onClick = { counter++ }) {Text("增加计数器")}
}
分析:DisposableEffect 的键是 counter。每次点击按钮使 counter 的值改变时,会先执行之前的清理操作,然后重新执行初始化操作。
注意: 1 避免在 onDispose 中执行耗时操作,onDispose 方法会在可组合项从组合中移除时立即执行,因此不要在其中执行耗时操作,以免影响 UI 的流畅性。如果需要执行耗时操作,建议使用协程或其他异步机制。2 确保资源的正确释放,在 onDispose 方法中,要确保正确释放所有在初始化操作中获取的资源,避免资源泄漏。例如,如果在初始化时注册了监听器,在 onDispose 中要确保注销该监听器。
与 LaunchedEffect 的区别
1 LaunchedEffect 主要用于在可组合项组合时启动协程执行异步操作,它关注的是异步任务的执行。
2 DisposableEffect 更侧重于资源的管理,即初始化和清理操作。虽然 LaunchedEffect 也会在可组合项移除时取消协程,但它不是专门用于资源清理的。