jetpack compose 副作用 SideEffect

SideEffect 用于将 Compose 内部状态安全地同步到外部非 Compose 世界。执行时机Composition 成功提交后、下一次重组之前。如果组合失败,SideEffect 不会执行。

场景 1:将 Compose 状态同步到外部对象

复制代码
@Composable
fun ChatScreen(viewModel: ChatViewModel) {
    val messages by viewModel.messages.collectAsState()
    val listState = rememberLazyListState()
    
    SideEffect {
        // 把滚动位置同步给 ViewModel 做持久化
        viewModel.saveScrollPosition(listState.firstVisibleItemIndex)
    }
}

场景 2:分析埋点

复制代码
@Composable
fun ProductPage(product: Product, tracker: AnalyticsTracker) {
    SideEffect {
        tracker.logEvent("product_view", mapOf("id" to product.id))
    }
}

注意事项

1、不要在 SideEffect 里修改 Compose State --- 会导致无限重组循环

2、适合"读"操作,不适合"写"操作 --- 它是同步出去,不是触发变化

3、如果需要异步操作,用 LaunchedEffect 而不是 SideEffect

源码

复制代码
// 1. SideEffect.kt 
@Composable
fun SideEffect(effect: () -> Unit) {
    currentComposer.recordSideEffect(effect)
}

和 snapshotFlow 的对比

对比项 SideEffect snapshotFlow
登记方式 recordSideEffect() → changes 列表 Snapshot.registerApplyObserver()
执行时机 Composition commit 成功 Global Snapshot apply 成功
失败处理 组合失败 → 丢弃 Snapshot apply 成功才回调
底层共同点 都依赖"记录→提交"模式,不是立即执行 都依赖"记录→提交"模式,不是立即执行

Snapshot 状态管理层 和 Composer UI 构建层

复制代码
Composition 层 (构建 UI 树)
    │
    │  依赖
    ▼
Snapshot 层 (管理状态读写)

Snapshot apply 发生在底层,Composition commit 发生在上层。一个改了状态值,一个改了 UI 树。

Snapshot apply 只是把数据标记为已确认,但 UI 树不一定刷新:

复制代码
// 场景:快速连续点击
button.onClick {
    count++  // → 触发 Snapshot apply(数据层)
    count++  // → 又触发一次 Snapshot apply
}
// 但 Composition 只会在下一帧跑一次重组
// → 两次 Snapshot apply,一次 Composition commit
对比项 Snapshot apply Composition commit
改了啥 State 值(变量层面) UI 节点树(LayoutNode 层面)
所在的层 Snapshot 系统 Composer 系统
触发者 MutableSnapshot.apply() 帧回调 + Composer
失败怎么办 几乎不会失败(纯数据合并) 可能失败(异常/中断 → 丢弃整棵树)
观察者 registerApplyObserver recordSideEffect
典型案例 snapshotFlow 在此回调 SideEffect 在此回调
相关推荐
北京自在科技9 小时前
谷歌 Find Hub 迎来新版本更新
android·安卓
古法安卓15 小时前
Android-休眠唤醒后onLocationChanged没有数据问题排查
android·java·android studio
Htr_18 小时前
Creem 2.0 使用指南:面向 AI 构建时代的资金平台
android·数据库·人工智能·ui·photoshop
wardenlzr19 小时前
车机看门狗(Watchdog)为何会让整机硬重启
android·优化·车机
IT毕设实战小研19 小时前
基于大数据的商场商铺数据分析与可视化的设计与实现
android·java·大数据·django·课程设计
aqi0020 小时前
一文读懂 HarmonyOS 7.0 带来的十大API重要升级
android·华为·harmonyos·鸿蒙·harmony
是店小二呀21 小时前
鸿蒙PC开源移植:CodeLite原生IDE与Remote Agent适配
android·智能手机·远程桌面
不要喷香水21 小时前
00-总览与架构
kotlin·app·档案管理
终端安全笔记1 天前
iOS 27 给了租赁一个新工具,但它只认受监督的设备
android·网络·安全·ios