本文内容来自 Android Developers Blog: What's new in the Jetpack Compose January '24 release
前几篇文章:
1.3.0:Jetpack Compose 上新:瀑布流布局、下拉加载、DrawScope.drawText
2024年1月24日,在历经了长达三个半月的等待后,Jetpack Compose 1.6 终于是姗姗来迟。这一版本专注于性能表现,团队继续完成着 Modifier 系统的迁移(迁移到 Modifier.Node 体系,详情见前几次的更新),并持续改进主要 API 的效率。
这一版本的 BOM 为 2024.01.00
gradle
implementation platform('androidx.compose:compose-bom:2024.01.00')
性能
性能仍然是 Compose 团队的最高优先级,这次更新在 1.5 基础 上进一步带来了滚动性能 ~20% 、以及启动时间 12% 的提升(基于它们的 benchmark)!而在 1.5 的那次 Release 中,大部分 App 已经可以通过升级版本看到这些变化(代码都不用改)。
对滚动和启动时间的优化来自于团队在内存分配、懒加载上的持续优化,以确保框架仅在必要情况下才执行。这些提升可以在 Compose 的各种 API 中得以体现,尤其是 Text、clickable、Lazy List 和 Graphics(包括 Vectors)。
团队也写了一份指南,帮助你基于 Modifier.Node
编写自己的 Modifier,见:developer.android.com/jetpack/com...
为外部类指定稳定性(Stability)
Compose Compiler 1.5.5 引入了一个新的选项,可提供一个配置文件以指明哪些类是 stable 的。此选项能允许你将任何类标为 Stable 的,包括自己模块的、外部库、标准库等,而无需修改这些模块或者包裹一层
注,以前的解决方案要么自己写一份,要么包一层,类似于
kotlin// 外部类 class UnstableClass(xxx) // 自己的模块 @Stable class Wrapper(val impl: UnstableClass)
先前的方式仍然可用,新的方式能让你更方便的额外告诉 Compose Compiler 哪些应该被视为 Stable。关于如何使用此配置,见此 创建自定义修饰符 | Jetpack Compose | Android Developers
生成代码的性能
Compose 编译器插件生成的代码也得到了改进。对这些代码进行微小调整可以带来巨大的性能改进,因为每个 Composable 中都会生成它们。Compose 编译器跟踪 Compose State 对象,以了解在值发生更改时应重组哪些 Composable ;然而,许多 State 的 value 仅会被读取一次,而有些根本不被读取,却仍经常发生更改!此更新允许编译器跳过不必要的跟踪。
Compose Compiler 1.5.6 还默认启用了 "固有记忆(intrinsic remember)"模式。该模式在编译时转换 remember,并会考虑用作 remember
的 keys
的各种 Composable 参数的信息。这加速了确定 remember
的值否需要重新计算的过程,但也意味着如果在调试过程中,在 remember 函数内设置断点,它可能不再被调用:因为编译器已经移除了 remember 的使用并用不同的代码替换了它。
实验性 强跳过模式
我们还在努力使您编写的代码自然变得更高效。我们希望为您直观编写的代码进行优化,而无需深入了解 Compose 内部原理来弄懂解 "为什么我的 Composable 莫名其妙重组了,不应该啊"
Compose 的此版本增加了对 "强跳过模式(Strong Skipping Mode)" 的实验性支持。强跳过模式放宽了有关哪些更改可以跳过重组的规则,更偏向于开发人员的期望。启用强跳过模式后,如果将相同的对象实例传递给其参数,具有不稳定参数的 Composable 也可以跳过重组。此外,强跳过模式还自动记住涉及不稳定值的 lambda(当前仅记住全 Stable 的 lambda)。
强跳过模式目前处于实验阶段,默认情况下处于禁用状态,因为我们认为它尚未准备好供生产使用。它预计将于 Compose 1.7 默认启用,在此之前,我们将持续评估其效果。请参阅我们的 指南 以尝试强跳过模式并帮助我们找到任何问题。
文本
默认字体填充(Padding)的更改
此版本现在将 includeFontPadding
设置默认为 false。includeFontPadding
是一个遗留属性,根据文本的第一行顶部和最后一行底部的字体度量值添加额外的 Padding。将此设置默认为 false 使默认文本布局更符合常见的设计工具,使其更容易与生成的设计规范匹配。升级到2024年1月发布版后,您可能会在文本布局和屏幕截图测试中看到细微变化。有关此设置的更多信息,请参阅 Fixing Font Padding in Compose Text 博文和 开发人员文档。
非线性字体缩放的支持
2024年1月发布版使用非线性字体缩放来提高文本的可读性和可访问性。非线性字体缩放通过应用非线性缩放曲线,防止屏幕上的大文本元素过大缩放。这种缩放策略意味着大文本的缩放倍率与较小文本不同。
拖放
Compose Foundation 添加了对平台级拖放的支持,使内容可以在多窗口模式下的设备上在应用程序之间进行拖放。该 API 与 View API 完全兼容,这意味着从View 开始的拖放可以拖到 Compose 中,反之亦然。要使用此API,请参阅代码示例。
其他变更
此版本还包括如下变更:
- 在 Lazy lists 中支持了
LookaheadScope
- 修复了 在 Lazy List 中不活跃但仍存活(为了复用)的 composables 在默认情况下未被语义树正确过滤
- 动画中支持 基于 Spline 的 keyframes
- 添加支持 鼠标选择,包括文本
开始吧
由衷感谢所有在 issue tracker 提出的 bug 报告和 feature requests,这帮助我们优化 Compose,并构建你所期望的 API。欢迎继续为我们提出反馈,帮助 Compose 变得更好!
想看看接下来会发生什么?看看我们的 路线图,了解我们目前所想、所做的。
Happy Composing!
原文结束。
实际 APK 体验
光说不练假把式,实际到底是什么效果也只有真的运行下才知道。正好我自己维护的开源一对多+大模型翻译软件 FunnySaltyFish/FunnyTranslation: 基于Jetpack Compose开发的翻译软件,支持多引擎、插件化~ | Jetpack Compose+MVVM+协程+Room 就有现成的代码,我临时升级到 Compose 1.6(其余无更改) ,打了一个 release 的共存包(在原包名基础上添加了 .tmp
后缀,各位有兴趣可以自己下载体验体验
- Compose 1.5:FunnyTranslation/translate/common/release/commonRelease.apk
- Compose 1.6:FunnyTranslation/translate/common/release/commonReleaseCompose1_6.apk
其中的 侧边栏-致谢
为长分页列表,可以自己滑动试试
另外,这个项目正在向 Kotlin + Compose 跨平台迁移,目前已经跑起来了,有兴趣的同学欢迎前往 FunnySaltyFish/Transtation-KMP: A translation app on Android/Desktop built by Kotlin Multiplatform + Compose Multiplatform, enjoy amazing experience with LLMs' support 体验