一、RememberObserver / RetainObserver 是什么?

先给一句官方级定义

它们是“状态对象的生命周期回调接口”,不是 UI API,也不是业务 API。

换句话说:

它们是给“状态对象自己”用的,不是给 Composable 直接调用的。


RememberObserver

当一个对象被 remember { ... } 保存时,Compose 允许这个对象接收 组合生命周期回调

interface RememberObserver {
    fun onRemembered()
    fun onForgotten()
    fun onAbandoned()
}

生命周期语义(非常重要)

回调 含义
onRemembered() 对象真正进入 Composition
onForgotten() 对象被移出 Composition
onAbandoned() 组合被中断,对象从未真正被使用

RetainObserver

当对象通过 retain { ... } 保存(跨配置变化)时,使用的是 Retain 生命周期

interface RetainObserver {
    fun onRetained()
    fun onRetired()
    fun onUnused()
}

生命周期语义

回调 含义
onRetained() 对象被保留用于下一个配置
onRetired() 对象不再被保留
onUnused() retain 发生但对象未被真正使用

二、它们到底解决了什么问题?

核心问题一句话:

Compose 中,对象的构造 ≠ 对象真正被使用

为什么这是个问题?

Compose 在以下情况下会:

  • 创建对象
  • 但又立刻放弃
  • 或因为重组 / 分支变化而丢弃
val manager = remember {
    Manager() // ⚠️ 构造函数可能被调用
}

👉 构造函数调用,并不意味着它会长期存在


错误做法(官方明确反对)

class Manager {
    init {
        startListening() // ❌ 非常危险
    }
}

如果对象马上被 abandoned:

  • 监听已启动
  • 但永远没有清理
  • 泄漏 / 重复注册

三、正确用法(官方推荐)

1️⃣ RememberObserver 的正确姿势

class Manager : RememberObserver {

    override fun onRemembered() {
        startListening()   // ✅ 真正被使用时
    }

    override fun onForgotten() {
        stopListening()    // ✅ 被移除时清理
    }

    override fun onAbandoned() {
        // 一般什么都不做
    }
}
@Composable
fun Screen() {
    val manager = remember { Manager() }
}

2️⃣ RetainObserver 的正确姿势

class Player : RetainObserver {

    override fun onRetained() {
        prepare()
    }

    override fun onRetired() {
        release()
    }

    override fun onUnused() {
        // retain 但没用到
    }
}
@Composable
fun PlayerScreen() {
    val player = retain { Player() }
}

四、那我平时为啥根本没见过它们?

因为官方 不希望在业务代码里用它们

这是重点。


官方推荐的替代方案(更熟)

场景 推荐方式
启动副作用 LaunchedEffect
注册 / 反注册 DisposableEffect
长期状态 ViewModel
资源管理 rememberCoroutineScope

举个对比(非常重要)

❌ 用 RememberObserver(业务里不推荐)
class UiTracker : RememberObserver { ... }
✅ 用 DisposableEffect(官方推荐)
@Composable
fun Screen() {
    DisposableEffect(Unit) {
        startTracking()
        onDispose { stopTracking() }
    }
}

官方为什么不鼓励用 Observer?

  1. API 偏底层
  2. 极易被误用
  3. 难测试
  4. 不直观
  5. Composable 级别的 Effect 已经覆盖 99% 需求

五、那什么时候“真的需要”它们?

只有这 3 种情况(非常少)


1️⃣ 写库 / 框架 / 基础组件

  • 自定义状态容器
  • Compose 基础设施
  • UI 工具库

👉 不是在写业务代码


2️⃣ 状态对象本身必须管理副作用

例如:

  • 播放器
  • 渲染引擎
  • 原生资源句柄

👉 副作用和对象本身强绑定


3️⃣ retain + 资源管理(高级用法)

retain { Engine() }

且:

  • Engine 自己知道何时 prepare / release
  • 不能交给 Composable 层

六、为什么公司项目里“没用到”是好现象?

因为这说明:

  • 项目在用 正确的高层 API
  • 副作用在 Composable 层管理
  • 状态和资源职责清晰
  • 没滥用底层机制

👉 这不是落后,是成熟


七、给一个“工程师级结论”

RememberObserver / RetainObserver
是 Compose 的“底层生命周期钩子”,
而不是日常开发工具。

如果你在业务代码里大量看到它们:

  • ⚠️ 设计可能有问题

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐