Android Compose 中,@Immutable 和 @Stable 的理解

Jetpack Compose 中的稳定性(Stability)

Compose 编译器通过分析对象的稳定性来决定是否跳过重组(Recomposition)。如果一个对象被认为是"稳定"的,那么当它作为参数传入到 Composable 函数中时,只要引用没有变化,Compose 就可以跳过对该函数的重组。 参考 developer.android.com/develop/ui/... developer.android.com/develop/ui/...

1.@Immutable

表示这个类是完全不可变的(immutable),所有属性都是 val 且不会改变。

Compose 编译器会认为这样的对象在整个生命周期内都不会发生变化。

特点: 所有字段必须是 val。 推荐用于数据模型类(如:用户信息、配置等)。 适用于纯数据类,比如 Kotlin 的 data class。 可以安全地跳过重组,提高性能。

kotlin 复制代码
@Immutable 
data class User(val id: Int, val name: String)
如果你试图用 var 字段,编译器会警告你该类可能不稳定。

2.@Stable

表示这个类是"稳定的",但允许包含可变字段(如 var),前提是这些字段的变化不会影响 UI 的状态,或者你已经通过 Compose 的响应式机制(如 mutableStateOf)管理了其变化。

特点: 允许使用 var。 需要开发者自己保证类的行为符合"稳定性"要求。 如果某个字段确实会变化但你不希望触发重组,可以用 @Stable 告诉 Compose 忽略它。 如果你想让某些字段变化也能触发重组,可以在这些字段中使用 mutableStateOf()。

kotlin 复制代码
@Stable 
class Counter { 
    var name:String ="abc"
    var count by mutableStateOf(0)
    private fun increment() { count++ }
}
`count` 是 `var`,但它是一个 `mutableStateOf`,
Compose 能追踪它的变化并触发重组。
整个 `Counter` 类被标记为 `@Stable`,
Compose 认为它是稳定的,不会因为 name 改变而进行重组,因为 Compose 不会追踪它的变化,
除非 `count` 改变,否则不会重组。
html 复制代码
使用 @Stable 的注意事项
如果你滥用 @Stable,可能会导致:
状态更新不触发重组 → 页面无法刷新。
性能优化过度 → UI 不同步于数据。
所以建议:
如果类是纯粹的数据结构,优先使用 @Immutable。
如果类封装了一些逻辑或状态管理,再考虑使用 @Stable。
永远不要对会频繁变化的类使用 @Stable,除非你知道自己在做什么。

ompose 如何判断稳定性?
Compose 编译器会根据以下规则判断一个类是否稳定:

判断条件	                                  是否稳定
所有属性是 val,且类型稳定	                 ✅ 是(默认 @Immutable)
使用了 @Stable 注解	                         ✅ 视为稳定
包含 mutableStateOf 或其他可观察类型       	 ✅ 可追踪变化
属性是 var,未使用任何注解	                 ❌ 不稳定

总结

在 Android Compose 中,@Immutable 和 @Stable 都是用来声明稳定性的,告诉编译器,如果你定义了普通的 class类对象,里面的字段不是 val 的那么,compose 会统一认为是不稳定的,就会进行重组,Compsoe提供了@Immutable注解,这个注解的类必须是 val 不可变的,就很稳定了。@Stable 声明的类是告诉 Compose 我很稳定,即使我有var 字段的变量,我也很稳定,可以跳过重组,但是这样话,如果值发生变化,compose 就追踪不了,无法重组,页面就无法发生变化,这是不对的,当然你可以在@Stable定义的类中,定义 compose 可追踪的状态,例如muatbleStateOf()。当发生变化,就会重组,进行页面变化了。

相关推荐
data analyse 4561 分钟前
埋点工具的私有化部署成本高吗?
前端·数据分析·github
data analyse 45644 分钟前
埋点工具的埋点查询语言难学吗?
前端·数据分析
DianSan_ERP1 小时前
多平台订单自动下载与回传的技术实现:从消息推送到状态闭环引言
java·linux·服务器·前端·网络·架构·自动化
恋猫de小郭1 小时前
Shopify 回应为什么从 RN 回到原生,为什么不用 KMP ?
android·前端·flutter
小蜗 strong1 小时前
和电脑猜拳(随机程序应用)
服务器·前端·python
下家3 小时前
为了脱离前端鄙视链,于是自己写个框架 - React 党看完沉默了
前端·前端框架
zhiyouTech3 小时前
从“被看见“到“被信任“:关于信源评级机制的一点观察
大数据·前端·人工智能
Hashan3 小时前
Vibe Coding 下前后端怎么对接接口?后端不给力的兜底方案
前端·后端·vibecoding
你挚爱的强哥4 小时前
【sgKeyboard】自定义组件:虚拟键盘
前端·javascript·计算机外设
锅里游的鱼吖4 小时前
echarts自定义折线图
前端·javascript·数据库