Compose 将类型视为稳定或不稳定。如果某个类型是稳定的类型 不可变,或者 Compose 是否可以知道其值是否具有 在重组之间发生了变化如果 Compose 无法确定类型是否不稳定,请按以下步骤操作: 其值在重组后发生了变化。
Compose 使用可组合项参数的稳定性来确定它是否 可以在重组期间跳过可组合项:
- 稳定的参数:如果可组合项具有未 Compose 会跳过它。
- 参数不稳定:如果可组合项的参数不稳定,Compose 在重组组件的父项时始终会对其执行重组。
如果应用包含许多不必要的不稳定组件,Compose 会始终这些组件 重组时,可能会出现性能问题和其他问题。
本文档详细介绍了如何提高应用的稳定性以改进 性能和整体用户体验。
不可变对象
以下代码段演示了稳定性和 重组。
Contact
类是一个不可变的数据类。这是因为
形参是使用 val
关键字定义的基元。创建
Contact
的实例,则无法更改该对象属性的值。
如果您尝试这样做,则会创建一个新对象。
data class Contact(val name: String, val number: String)
ContactRow
可组合项有一个 Contact
类型的形参。
@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
var selected by remember { mutableStateOf(false) }
Row(modifier) {
ContactDetails(contact)
ToggleButton(selected, onToggled = { selected = !selected })
}
}
考虑一下,当用户点击切换按钮和
selected
状态变化:
- Compose 会评估是否应重组
ContactRow
中的代码。 - 它发现
ContactDetails
的唯一参数是Contact
类型。 - 由于
Contact
是一个不可变的数据类,因此 Compose 可确保ContactDetails
的参数已更改。 - 因此,Compose 会跳过
ContactDetails
,并且不会重组它。 - 另一方面,
ToggleButton
的参数已更改, Compose 会重组该组件。
可变对象
虽然前面的示例使用的是不可变对象,但您可以创建一个 可变对象。请参考以下代码段:
data class Contact(var name: String, var number: String)
由于 Contact
的每个参数现在都是 var
,因此类不再是不可变的。
如果其属性发生更改,Compose 不会感知。这是因为
Compose 仅跟踪对 Compose 状态对象的更改。
Compose 认为此类类不稳定。Compose 不会跳过重组
不稳定的类。因此,如果以这种方式定义 Contact
,ContactRow
只要 selected
发生变化,前面的示例中便会重组。
在 Compose 中实现
考虑 Compose 究竟是如何实现的,虽然并不重要,但会很有帮助 确定在重组期间要跳过的函数。
当 Compose 编译器对代码运行时,它会标记每个函数和类型 。这些标记反映了 Compose 处理函数的方式, 类型。
函数
Compose 可以将函数标记为 skippable
或 restartable
。请注意,
将函数标记为其中之一、两者或一个也不:
- 可跳过:如果编译器将可组合项标记为可跳过,Compose 可以 如果它的所有参数都等于它们,则在重组期间会跳过它 先前的值。
- 可重启:可重启的可组合项充当“作用域”其中 可以开始重组。换句话说,该函数可以是 条目,指明 Compose 可在什么之后开始重新执行代码以进行重组 状态更改
类型
Compose 将类型标记为不可变或稳定。每种类型都为 其他:
- 不可变:如果某个类型的值已发生变化,Compose 会将其标记为不可变。
属性永远不能更改,并且所有方法都是引用透明的。
- 请注意,所有基元类型都标记为不可变。这些国家/地区包括
String
、Int
和Float
。
- 请注意,所有基元类型都标记为不可变。这些国家/地区包括
- Stable:表示在构造后其属性可以更改的类型。 如果这些属性在运行时发生变化,以及何时发生变化,Compose 会 这些更改
调试稳定性
如果您的应用要重组参数未更改的可组合项,请先
检查其定义,看看是否存在明显可变的参数。始终撰写
如果您传入具有 var
属性的类型或 val
,则重组组件
属性。
如需详细了解如何在 Compose,请参阅调试稳定性指南。
解决稳定性问题
如需了解如何为 Compose 实现带来稳定性,请参阅 解决稳定性问题指南。
摘要
总体而言,您应注意以下几点:
- 参数:Compose 会确定代码中每个参数的稳定性 可组合项,以确定在运行期间应跳过哪些可组合项 重组。
- 立即修复:如果您发现自己的可组合项没有被跳过并且
导致性能问题,则应检查导致
不稳定,例如
var
参数。 - 编译器报告:您可以使用编译器报告 确定推断出的类的稳定性。
- 集合:Compose 始终认为集合类不稳定,例如
为
List, Set
和Map
。这是因为我们无法保证 不可更改。您可以改用 Kotlinx 不可变集合,或者 为类添加@Immutable
或@Stable
注解。 - 其他模块:Compose 始终认为其来源位置不稳定 不运行 Compose 编译器的模块。在界面中封装类 模型类。