强烈的跳过模式

强式跳过是 Compose 编译器中提供的一种模式。启用后, 以两种方式更改编译器的行为:

  • 参数不稳定的可组合项变为可跳过
  • 系统会记住捕获不稳定的 Lambda

启用强力跳过模式

如需为 Gradle 模块启用强跳过功能,请在 Gradle 配置的 composeCompiler 代码块:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

可组合项可跳过性

强跳过模式会放宽通常应用的一些 stability 规则 由 Compose 编译器手动定义。修改者 默认情况下,Compose 编译器会将可组合函数标记为可跳过(如果 其参数具有稳定的值。强跳过模式可以改变这一点。

启用强跳过功能后,所有可重启的可组合函数都会变为 可跳过的广告无论它们的参数是否不稳定,这一点都适用。 不可重启的可组合函数仍不可跳过。

何时跳过

为了确定是否在重组期间跳过可组合项,Compose 会比较 每个参数值及其之前的值。比较类型 取决于参数的 stability

  • 不稳定参数使用实例等式 (===) 进行比较
  • 使用对象相等性 (Object.equals()) 比较稳定参数

如果所有参数都满足这些要求,Compose 会跳过可组合项, 重组。

您可能希望可组合项停用强劲跳过功能。也就是说, 想要一个可重启但不可跳过的可组合项。在这种情况下,请使用 @NonSkippableComposable 注解。

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

为类添加稳定版注解

如果您希望对象使用对象相等而不是实例相等, 继续使用 @Stable 为给定类添加注解。您可以参考 在观察对象的完整列表时, 因为 Room 会在出现以下情况时随时为列表中的每一项分配新对象: 这些更改

Lambda 记忆

强跳过模式还支持更多 lambda 的“记忆” 。启用强跳过功能后, 可组合函数。

示例

为了在使用强跳过时记住可组合项内的 lambda, 编译器会使用 remember 调用封装 lambda。它与 lambda 的捕获。

假设您有一个 lambda,如以下示例所示:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

启用强跳过功能后,编译器会通过将 lambda 封装到内来记住 lambda remember 调用:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

这些键遵循与可组合函数相同的比较规则。运行时 使用实例相等性比较不稳定的键。它会使用 对象是否相等。

记忆和重组

这项优化大大增加了运行时 在重组期间跳过。如果不执行记忆操作, 将新的 lambda 分配给接受 lambda 形参的任何可组合项, 重组。因此,新 lambda 的形参不等于 最后一段组合这会导致重组。

避免记忆

如果您有不想记住的 lambda,请使用 @DontMemoize 注解。

val lambda = @DontMemoize {
    ...
}

APK 大小

经过编译后,可跳过的可组合项会导致生成的代码多于 不可跳过的可组合项启用强跳过功能后,编译器 将几乎所有可组合项标记为可跳过,并将所有 lambda 封装在 remember{...}。因此,启用强跳过模式 对应用的 APK 大小的影响。

Now In Android 中启用强跳过会导致 APK 增加 大小为 4kB。大小的差异很大程度上取决于 指定应用中存在但应显示的不可跳过的可组合项 相对较小。