当前位置: 首页 > article >正文

Jetpack Compose 中,DisposableEffect、LaunchedEffect 和 sideEffect 区别和用途

在 Jetpack Compose 中,DisposableEffectLaunchedEffect 和 sideEffect 都是用于处理副作用(Side Effects)的 API,但它们的用途和触发时机不同。以下是它们的核心概念和区别:

1. 副作用(Side Effect)是什么?

副作用是指 Composable 函数中与界面渲染无关的操作,例如:

  • 发起网络请求

  • 订阅/取消订阅数据流

  • 修改外部变量或状态

  • 访问 Android 系统 API(如权限、生命周期)

由于 Composable 函数可能会频繁重组(Recomposition),副作用需要被可控地管理,避免重复执行或资源泄漏。

2. 三者的对比

API用途触发时机清理机制适用场景
LaunchedEffect在 Composable 中启动一个协程,执行挂起函数(如异步任务)。当 key 变化时,会取消之前的协程并重新启动。自动取消协程一次性异步操作(如网络请求、动画)。
DisposableEffect执行需要清理的资源操作(如监听器、订阅)。当 key 变化时,先执行清理逻辑,再重新执行副作用。需手动清理(onDispose需要释放资源的操作(如广播、RxJava 订阅)。
sideEffect在每次成功重组后执行的非阻塞操作,不依赖重组是否跳过。每次重组后(即使其他部分跳过重组)。更新外部状态(如 Analytics 日志、非关键状态同步)。

3. 详细说明与代码示例

(1) LaunchedEffect
  • 用途:在 Composable 中安全启动协程,适合异步任务。

  • 特点

    • 自动取消:当 key 变化或 Composable 退出时,协程会被取消。

    • 必须指定 key(用于控制重启条件)。

@Composable
fun TimerDemo() {var time by remember { mutableStateOf(0) }LaunchedEffect(Unit) { // 传入 Unit 表示只启动一次while (true) {delay(1000)time++}}Text("Time: $time")
}
(2) DisposableEffect
  • 用途:管理需要手动释放的资源(如监听器、订阅)。

  • 特点

    • 必须调用 onDispose 清理资源。

    • key 变化时,先执行 onDispose,再重新初始化。

  • @Composable
    fun SensorDemo() {val sensorManager = remember { getSystemService(Context.SENSOR_SERVICE) as SensorManager }var data by remember { mutableStateOf(0f) }DisposableEffect(Unit) {val listener = object : SensorEventListener {override fun onSensorChanged(event: SensorEvent) {data = event.values[0]}override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}}sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL)onDispose { // 必须清理!sensorManager.unregisterListener(listener)}}Text("Sensor value: $data")
    }
(3) sideEffect
  • 用途:在重组后执行非阻塞操作,通常用于与 Compose 无关的状态同步。

  • 特点

    • 每次重组后都会执行(即使其他部分跳过了重组)。

    • 无清理机制,适合轻量级操作。

@Composable
fun AnalyticsButton(clicked: Boolean) {Button(onClick = { /* ... */ }) {Text("Click Me")}sideEffect {if (clicked) {logAnalyticsEvent("ButtonClicked") // 记录日志}}
}

4. 关键区别总结

场景LaunchedEffectDisposableEffectsideEffect
异步任务✅(协程)
需要清理的资源✅(监听器、订阅)
重组后状态同步✅(日志、统计)
自动取消/清理✅(协程)✅(需手动 onDispose

5. 如何选择?

  • 需要协程? → LaunchedEffect

  • 需要释放资源? → DisposableEffect

  • 只需在重组后同步状态? → sideEffect

通过合理使用这些 API,可以避免副作用导致的性能问题或内存泄漏。

http://www.lryc.cn/news/2404464.html

相关文章:

  • STM32开发,创建线程栈空间大小判断
  • 正则表达式检测文件类型是否为视频或图片
  • Qwen大语言模型里,<CLS>属于特殊的标记:Classification Token
  • TDengine 开发指南——无模式写入
  • 分布式互斥算法
  • 第34次CCF-CSP认证真题解析(目标300分做法)
  • video-audio-extractor:视频转换为音频
  • rk3588 区分两个相同的usb相机
  • [概率论基本概念4]什么是无偏估计
  • 乐观锁与悲观锁的实现和应用
  • PL/SQLDeveloper中数值类型字段查询后显示为科学计数法的处理方式
  • 【vue】Uniapp 打包Android 文件选择上传问题详解~
  • ASR技术(自动语音识别)深度解析
  • 图论水题2
  • Ctrl-Crash 助力交通安全:可控生成逼真车祸视频,防患于未然
  • 网络编程之服务器模型与UDP编程
  • Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测
  • 阿里云服务器安装nginx并配置前端资源路径(前后端部署到一台服务器并成功访问)
  • Ubuntu 下开机自动执行命令的方法
  • C++11新增重要标准(下)
  • 【第六篇】 SpringBoot的日志基础操作
  • Pluto论文阅读笔记
  • ubuntu显示器未知
  • Faiss向量数据库全面解析:从原理到实战
  • matlab 2024a ​工具箱Aerospsce Toolbox报错​
  • 使用有限计算实现视频生成模型的高效训练
  • Server2003 B-1 Windows操作系统渗透
  • 一次Oracle的非正常关闭
  • AI不会杀死创作,但会杀死平庸
  • JeecgBoot低代码管理平台