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()。当发生变化,就会重组,进行页面变化了。

相关推荐
JeffongTan1 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
陆枫Larry4 小时前
Astro 是什么
前端
是立不是利5 小时前
写给设计师的 CSS 博客美学指南
前端·css
默_笙6 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师6 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen6 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员
a1117766 小时前
Shirone 二次元博客主题 开源
前端·开源
IT_陈寒6 小时前
Python的切片赋值把我坑惨了,这不是bug是特性
前端·人工智能·后端
掘金酱6 小时前
【社区公告】致每一位掘友:关于这次调整, 想再说几句
前端·人工智能
CoderLiu6 小时前
程序化工具调用(PTC)与动态工作流引擎:深入大模型工具调用的架构演进与实践
前端·人工智能·后端