性能改进,DevTools更新,新的Material You支持,新的应用模板,以及更多
发布时间:2021年9月8日 - 18分钟阅读
你好,欢迎来到Flutter 2.5! 这是一个很大的版本,在Flutter发布的历史上,它的统计数字是第二高的。4600个问题被关闭,3932个PR被合并,来自252个贡献者和216个审查者。如果我们回顾一下去年,我们看到1337个贡献者创建了21072个PR,其中15172个被合并。虽然 "Flutter有什么新功能 "的博文集中在新功能上,但我们在Flutter上的首要工作是始终确保您拥有您所需要的功能,并尽可能达到最高的质量水平。
而事实上,这个版本延续了一些重要的性能和工具的改进,以追踪你自己的应用程序的性能问题。同时,还有一些新的功能,包括对Android的全屏支持,更多的Material You(也叫v3)支持,更新了文本编辑以支持可切换的键盘快捷键,在Widget Inspector中更详细地查看你的小部件,在Visual Studio Code项目中添加依赖关系的新支持,从IntelliJ/Android Studio的测试运行中获得覆盖信息的新支持,以及一个全新的应用模板,作为你真实世界Flutter应用的更好基础。这个版本充满了令人兴奋的新更新,所以让我们开始吧。
性能:iOS着色器预热、异步任务、GC和消息传递
这个版本有几个性能改进。首先是一项PR,用于从离线训练运行中连接金属着色器预编译(#25644),这(正如我们的基准测试所显示的)将最坏情况下的帧光栅化时间减少了2/3,将第99百分位的帧减少了一半。我们继续在减少iOS干扰方面取得进展,这是在这条道路上迈出的另一步。然而,着色器预热只是干扰的一个来源。以前,处理来自网络、文件系统、插件或其他隔离物的异步事件可能会中断动画,这是另一个干扰源。在本版本中对UI隔离器事件循环的调度策略(#25789)进行了改进,现在帧处理优先于其他异步事件的处理,在我们的测试中消除了来自这一来源的干扰。
由于前后处理异步事件结果导致的帧滞后
另一个导致卡顿的原因是当垃圾收集器(GC)暂停UI线程以回收内存时。以前,一些图像的内存只会在Dart虚拟机执行GC时被懒惰地回收。在早期版本中,作为一种变通方法,Flutter引擎会向Dart VM提示,图像内存可以通过GC回收,这在理论上可以导致更及时的内存回收。不幸的是,在实践中,这导致了太多的主要GC,而且内存有时仍然不能被快速回收,以避免在内存有限的设备上出现低内存的情况。在这个版本中,未使用的图像的内存被急于回收(#26219, #82883, #84740),大大减少了GCs。
添加修复前和修复后的GC,以急切地回收未使用的大图像内存
例如,在我们的一个测试中,播放一个20秒的GIF动画,从需要400多个GCs到只需要4个。更少的主要GCs意味着涉及图像出现和消失的动画将有更少的干扰,并消耗更少的CPU和电力。
Flutter 2.5的另一个性能改进是在Dart和Objective-C/Swift(iOS)或Dart和Java/Kotlin(Android)之间发送消息时的延迟问题。作为调整消息通道的一部分,从消息编解码器中删除不必要的副本,根据消息的大小和设备,延迟最多可减少50%(#25988,#26331)。
之前和之后的iOS消息延迟
你可以在Aaron Clarke的《提高Flutter中的平台通道性能》博文中阅读更多关于这项工作的细节。
如果你的目标是iOS,还有最后一项性能更新。在这个版本中,建立在苹果Silicon M1 Macs上的Flutter应用程序在ARM iOS模拟器上原生运行(#pull/85642)。这意味着在英特尔x86_64指令和ARM之间没有Rosetta翻译,这在你的iOS应用测试中提高了性能,并允许你避免一些微妙的Rosetta问题(#74970,#79641)。这是在Flutter中全面支持苹果硅的道路上迈出的又一步。请继续关注更多信息。
Dart 2.14:格式化、语言特性、pub和linting开箱即用
当然,没有Dart语言和运行时间,Flutter就不是Flutter,它是建立在Dart语言和运行时间之上的。这个版本的Flutter包含了Dart 2.14。新版本的Dart带有新的格式化,使级联更加清晰,新的pub支持忽略文件,以及新的语言功能,包括传奇的三段式移位运算符的回归。此外,也是Dart 2.14最棒的地方之一,这个版本创建了一套新的Dart和Flutter项目之间共享的标准行,开箱即用。
flutter create开箱即有一个Analysis_options.yaml文件,其中预先填充了推荐的Flutter线程。
当您创建一个新的Dart或Flutter项目时,您不仅可以得到这些衬垫,而且只需几个步骤,您也可以在您现有的应用程序中添加同样的分析。关于这些衬垫的细节,新的语言功能和更多,请查看Dart 2.14的发布公告。
框架。安卓全屏、Material You和文本编辑快捷键
Flutter 2.5版本包括对框架的一些修复和改进。从安卓开始,我们修复了一组围绕全屏模式的相关问题,它们之间有近100个大拇指。这些模式本身的名称使这成为我们最喜欢的新功能之一:靠后、粘性、粘性沉浸、边缘到边缘。这一变化还增加了一种方法,以倾听其他模式下的全屏变化。例如,如果用户参与应用,当系统UI回来时,开发者现在可以编写代码返回全屏或做其他事情。
新的安卓边到边模式:正常模式(左),边到边模式(中),带有自定义SystemUIOverlayStyle的边到边(右)。
在这个版本中,我们继续建立对新的Material You(又称v3)规范的支持,包括对浮动动作按钮尺寸和主题的更新(#86441),以及一个新的MaterialState.scrolledUnder状态,你可以通过PR中的示例代码(#79999)看到它的作用。
新的Material You FAB尺寸
新的MaterialState.scrolledUnder状态的运行情况
当我们在谈论滚动时,另一个改进是增加了滚动指标通知(#85221, #85499),即使用户没有滚动,它也会提供可滚动区域的通知。例如,下面显示了滚动条根据ListView的底层大小而适当出现或消失的情况。
新的滚动指标通知使滚动条在没有滚动的情况下自动出现和消失
在这种情况下,你不需要写任何代码,但如果你想捕捉ScrollMetricNotification的变化,你可以。特别感谢社区贡献者xu-baolin,他在这方面做了大量工作,并提出了一个很好的解决方案。
社区的另一个杰出贡献是为ScaffoldMessenger增加了材料横幅支持。你可能还记得Flutter 2.0版本公告中的ScaffoldMessenger,它是在屏幕底部显示SnackBars以向用户提供通知的一种更强大的方式。在Flutter 2.5中,你现在可以在你的脚手架顶部添加一个横幅,并保持原位,直到用户将其移除。
你的应用程序可以通过调用ScaffoldMessenger的showMaterialBanner方法来获得这种行为。
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('The MaterialBanner is below'),
),
body: Center(
child: ElevatedButton(
child: const Text('Show MaterialBanner'),
onPressed: () => ScaffoldMessenger.of(context).showMaterialBanner(
MaterialBanner(
content: const Text('Hello, I am a Material Banner'),
leading: const Icon(Icons.info),
backgroundColor: Colors.yellow,
actions: [
TextButton(
child: const Text('Dismiss'),
onPressed: () => ScaffoldMessenger.of(context)
.hideCurrentMaterialBanner(),
),
],
),
),
),
),
);
}
关于横幅的材料指南指出,你的应用程序应该一次只显示一个,所以如果你的应用程序多次调用showMaterialBanner,ScaffoldMessenger将保持一个队列,在前一个横幅被驳回时显示每个新的横幅。感谢Calamity210为Flutter中的材料支持提供的这一伟大补充
在Flutter 2.0及其新的文本编辑功能的基础上,如文本选择支点和能够在键盘事件被处理后停止传播,在这个版本中,我们增加了使文本编辑键盘快捷方式可被覆盖的能力(#85381)。如果你想让Ctrl-A做一些自定义操作,而不是选择所有文本,你可以这样做。DefaultTextEditingShortcuts类包含了Flutter在每个平台上支持的每个键盘快捷方式的列表。如果您想覆盖任何东西,请使用Flutter现有的Shortcuts小组件,将任何快捷键重新映射到现有或自定义的意图。您可以将该小组件放置在您的小组件树中您想要覆盖的地方。请看API参考中的一些例子。
插件:相机、图像选取器和附加插件
另一个经过大量改进的插件是相机插件。
- 3795 [camera] android-rework part 1: 支持Android相机功能的基础类
- 3796 [camera] android-rework part 2: Android自动对焦功能
- 3797 [相机]android-rework第三部分:Android曝光相关功能
- 3798 [相机]android-rework第4部分:Android闪光灯和变焦功能
- 3799 [相机]android-rework第五部分:Android FPS范围、分辨率和传感器方向功能
- 4039 [相机]android-rework第六部分:Android曝光和焦点功能
- 4052 [相机]Android-rework第七部分:Android降噪功能
- 4054 [相机] android-rework第8部分。最终实现的支持模块
- 4010 [相机]不要在iOS上触发平面设备方向
- 4158 [相机] 修复iOS上设置焦点和曝光点的坐标旋转问题
- 4197 [相机] 修复相机预览在方向改变时不总是重建的问题
- 3992 [相机] 防止设置不支持的FocusMode时崩溃
- 4151 [相机] 引入camera_web包
在image_picker插件上也做了很多工作,专注于端到端的相机体验。
- 3898 [image_picker] 图像采集器修复相机设备
- 3956 [image_picker] 在安卓系统上,将相机捕捉的存储位置改为内部缓存,以符合新的Google Play存储要求。
- 4001 [image_picker] 删除了多余的相机权限请求
- 4019 [image_picker] 当相机是一个源时,修复旋转。
这项工作改善了Android的相机和image_picker插件的功能和稳健性。此外,你会注意到一个早期版本的相机插件是有网络支持的(#4151)。这个预览版提供了对查看相机预览、拍摄照片、使用闪光灯和变焦控制的基本支持,所有这些都在网络上进行。它目前还不是一个被认可的插件,所以你需要明确地添加它来在你的网络应用中使用。
最初的Android相机重写工作是由acoutts贡献的。摄像头和图像采集器的工作由Baseflow完成,这是一家专门从事Flutter的咨询公司,因其在pub.dev上的软件包而闻名。camera_web的工作主要由Very Good Ventures完成,这是一家位于美国的Flutter咨询公司。非常感谢你们所有人对Flutter社区的贡献!
另一个有价值的社区贡献是由Flutter社区组织做出的,该组织以 "plus "插件闻名。随着Flutter这个版本的发布,Flutter团队的每一个相应的插件现在都带有一个推荐,就像这个推荐的电池。
此外,由于这些插件不再被积极维护,它们不再被标记为Flutter喜爱的插件。如果你还没有这样做,我们建议你转到以下插件的plus版本。
Flutter DevTools:性能,Widget inspector,和polish
这个版本的Flutter对Flutter DevTools进行了许多改进。首先是在DevTools中增加了对引擎更新的支持(#26205、#26233、#26237、#26970、#27074、#26617)。其中一组更新使Flutter能够更好地将跟踪事件与特定的帧联系起来,这有助于开发人员确定为什么一个帧可能会超出预算。你可以看到这反映在DevTools框架图表中,该图表已被重建为 "实时";当框架在你的应用程序中被渲染时,它们会被填充到该图表中。从这个图表中选择一个框架,就可以导航到该框架的时间线事件。
Flutter引擎现在也能识别时间线中的着色器编译事件。Flutter DevTools 使用这些事件来帮助您诊断应用程序中着色器编译的缺陷。
DevTools检测因着色器编译而丢失的帧
有了这个新功能,DevTools可以检测到您因着色器编译而丢失的帧,以便您可以修复这个问题。要像第一次一样运行您的应用程序(在您的着色器缓存被填充之前,就像任何用户一样),使用flutter run with the --purge-persistent-cache标志。这将清除缓存,以确保您重现用户在 "首次运行 "或 "重新打开"(iOS)时看到的环境。这项功能仍在开发中,所以请将你发现的问题或我们可以做出的任何改进归档,以帮助调试着色器编译的垃圾。
此外,当你追踪你的应用程序中的CPU性能问题时,你可能已经被来自Dart和Flutter库和/或引擎的本地代码的剖析数据淹没了。如果你想关闭其中任何一个以专注于你自己的代码,你可以通过新的CPU剖析器功能(#3236)来实现,该功能使你能够隐藏来自任何这些来源的剖析器信息。
对于任何你没有过滤掉的类别,它们现在已经被彩色编码(#3310,#3324),这样你就可以很容易地看到CPU框架图的哪些部分来自系统的哪些部分。
用彩色框架图来识别你的应用程序中的应用程序与原生程序与Dart与Flutter的代码活动
性能并不是你要调试的唯一东西。这个版本的DevTools带有Widget Inspector的更新,允许你将鼠标悬停在一个widget上,以评估该对象、查看属性、widget状态等。
而且,当你选择一个部件时,它会自动弹出在新的Widget Inspector Console中,在那里你可以探索该部件的属性。
当在断点处暂停时,你也可以从控制台评估表达式。
除了新的功能之外,Widget Inspector还进行了一次改头换面。为了使DevTools成为理解和调试Flutter应用程序的更有用的目的地,我们与芬兰的创意技术机构Codemate合作,进行了一些更新。
Flutter DevTools 抛光的用户体验,更易于使用
在这张截图中,您可以看到以下变化。
- 更好地传达调试切换按钮的作用--这些按钮有新的图标、面向任务的标签,以及丰富的工具提示,描述它们的作用和何时使用它们。每个工具提示都进一步链接到该功能的详细文档。
- 更容易扫描和定位感兴趣的小工具--Flutter框架中经常使用的小工具现在在检查器左侧的小工具树视图中显示图标。它们进一步根据其类别进行颜色编码。例如,布局小组件显示为蓝色,而内容小组件显示为绿色。此外,每个文本小组件现在都显示其内容的预览。
- 对齐布局探索器和小组件树的颜色方案--现在更容易从布局探索器和小组件树中识别同一个小组件。例如,下面的截图中的 "柱子 "部件在布局探索器中的背景是蓝色的,而在部件树视图中它有一个蓝色图标。
我们很想听听你对这些更新所产生的任何问题的看法,或者我们可以做出的任何其他改进,以确保DevTools工作得很棒。这些亮点只是一个开始。关于DevTools在Flutter这个版本中的全部新内容,请查看发布说明。
IntelliJ/Android Studio:集成测试、测试覆盖率和图标预览
Flutter的IntelliJ/Android Studio插件在这个版本中也进行了一些改进,首先是运行集成测试的能力(#5459)。集成测试是在设备上运行的整个应用测试,在integration_test目录下运行,并使用widget单元测试中相同的testWidgets()功能。
在 IntelliJ/Android Studio 中集成测试您的 Flutter 应用程序
要向您的项目添加集成测试,请按照flutter.dev上的说明进行。要将测试与 IntelliJ 或 Android Studio 连接,请添加一个运行配置,以启动集成测试,并连接一个设备供测试使用。运行配置允许你运行测试,包括设置断点、步进等。
此外,Flutter的最新IJ/AS插件允许你看到单元测试和集成测试运行的覆盖信息。您可以通过 "调试 "按钮旁边的工具栏按钮来访问这个信息。
覆盖率信息用红色和绿色的条子显示在编辑器的沟槽中。在这个例子中,第9-13行被测试,但第3和第4行没有被测试。
最新的版本还包括预览来自pub.dev的软件包中使用的图标的新功能,这些软件包围绕TrueType字体文件构建(#5504, #5595, #5677, #5704),就像Material和Cupertino图标支持预览一样。
IntelliJ/Android Studio中的图标预览
要启用图标预览,你需要告诉插件你正在使用哪些包。在插件的设置/首选项页面中有一个新的文本字段。
注意,这适用于定义为类中静态常量的图标,如屏幕截图中的示例代码所示。它对表达式不起作用,比如LineIcons.addressBook()或LineIcons.values['code']。如果你是一个图标包的作者,而这个图标包并不适用这个功能,请创建一个问题。
对于Flutter的IntelliJ/Android Studio插件,还有很多更新,您可以在发布说明中了解到。
- Flutter IntelliJ Plugin M57发布
- Flutter IntelliJ Plugin M58 发布
- Flutter IntelliJ Plugin M59 发布
- Flutter IntelliJ Plugin M60 发布
Visual Studio Code:依赖性、全部修复和测试运行器
Flutter的Visual Studio Code插件在这个版本中也得到了改进,首先是两个新的命令 "Dart: Add Dependency "和 "Dart: Add Dev Dependency"(#3306,#3474)。
在Visual Studio Code中添加Dart依赖性
这些命令提供的功能就像Jeroen Meijer的Pubspec Assist插件已经提供了一段时间。这些新命令开箱即用,提供了一个从pub.dev定期获取的包的类型到过滤器的列表。 你可能也会对 "修复所有 "命令(#3445, #3469)感兴趣,该命令可用于Dart文件,并能在一个步骤中修复所有与dart fix相同的问题,用于当前打开的文件。
使用Flutter修复规则来修复您代码中的所有已知问题
这也可以通过在编辑器.codeActionsOnSave VS Code设置中添加source.fixAll来设置为保存时运行。
或者,如果你想尝试一下预览功能,你可以启用dart.previewVsCodeTestRunner设置,看到Dart和Flutter测试通过新的Visual Studio Code测试运行器运行。
使用新的Visual Studio Code测试运行器测试您的Dart和Flutter代码
Visual Studio Code测试运行器看起来与当前的Dart和Flutter测试运行器有些不同,它将在不同的会话中坚持结果。Visual Studio Code测试运行器还增加了新的沟槽图标,显示测试的最后状态,可以点击它来运行测试(或右键点击上下文菜单)。
在未来的版本中,现有的Dart和Flutter测试运行器将被删除,而采用新的Visual Studio Code测试运行器。
而这仅仅是Visual Studio Code新功能和修复的冰山一角。关于所有的细节,请查看发布说明。
- v3.26 VS Code测试运行器集成,Flutter创建设置,...
- v3.25 额外的依赖管理改进,在文件/保存时修复所有,...
- v3.24 依赖关系树的改进,更容易启动配置,编辑器的改进
- v3.23 配置文件模式的改进,改进依赖关系树,改进LSP
工具:例外情况、新的应用模板和Pigeon 1.0
在以前的Flutter版本中,你可能会因为一些异常而感到沮丧,你期望这些异常被解除处理,这样你就可以触发调试器并找出它们的源头,但却发现Flutter框架没有让异常通过来触发调试器中的 "未处理的期望 "处理程序。在这个版本中,调试器现在可以正确地中断未处理的异常,而以前这些异常只是被框架捕获(#17007)。这改善了调试体验,因为你的调试器现在可以直接指向他们代码中的抛出行,而不是指向框架深处的一个随机行。一个相关的新功能使您能够决定FutureBuilder是否应该重新抛出或吞噬错误(#84308)。这应该会给你带来大量额外的异常,以帮助你追踪Flutter应用程序中的问题。
自从Flutter诞生以来,就有了Counter应用模板,它有很多优点:它展示了Dart语言的很多特性,演示了几个关键的Flutter概念,而且它足够小,即使有很多解释性的评论,也能装进一个文件。然而,它所做的并不是为真实世界的Flutter应用提供一个特别好的跳板。在这个版本中,有一个新的模板(#83530)可以通过以下命令获得。
$ flutter create -t skeleton my_app
运行中的新 Flutter 骨架模板
该骨架模板生成了一个两页的列表视图Flutter应用程序(带详细视图),遵循社区最佳实践。它的开发经过了大量的内部和外部审查,以提供一个更好的基础来建立一个生产质量的应用程序,并支持以下功能。
- 使用ChangeNotifier来协调多个小工具
- 默认情况下使用arb文件生成本地化信息
- 包括一个示例图像并为图像资产建立1x、2x和3x文件夹
- 使用 "功能优先 "的文件夹组织方式
- 支持共享偏好
- 支持浅色和深色主题
- 支持多个页面之间的导航
随着时间的推移,随着Flutter最佳实践的发展,希望这个新模板也能随之发展。
如果在光谱的另一端,你正在开发一个插件而不是一个应用程序,你可能会对1.0版本的Pigeon感兴趣。Pigeon是一个代码生成工具,用于生成Flutter和其主机平台之间的类型安全互操作代码。它允许你定义你的插件的API描述,并生成Dart、Java和Objective-C的骨架代码(分别可用于Kotlin和Swift)。
生成的Pigeon代码样本
Pigeon已经被用于Flutter团队的一些插件中。这个版本提供了更多有用的错误信息,增加了对泛型、原始数据类型作为参数和返回类型以及多参数的支持,预计它在未来会被更多地使用。如果你想在你自己的插件或添加到应用的项目中利用Pigeon,你可以在pigeon插件页面找到更多信息。
突破性变化和弃用
以下是Flutter 2.5版本中的突破性变化。
- 默认的拖动滚动设备
- v2.2版之后删除了废弃的API
- 引入软件包:flutter_lints
- ThemeData的口音属性已被弃用
- 清理手势识别器
- 用collate取代AnimationSheetBuilder.display
- 使用HTML插槽在网络中渲染平台视图
- 将LogicalKeySet迁移至SingleActivator
关于自1.17版本以来的全部突破性变化列表,请参见flutter.dev。
随着我们继续更新Flutter Fix(可在您的IDE中使用,也可通过dart fix命令使用),我们总共有157条规则可以自动迁移您受这些或过去的突破性变化以及任何弃用影响的代码。一如既往,我们非常感谢社区提供的测试,它们帮助我们识别了这些突破性变化。要了解更多,请查看我们的突破性变化政策。
另外,随着Flutter 2.5的发布,我们将放弃对iOS 8的支持,正如2020年9月宣布的那样。放弃对市场份额不足1%的iOS 8的支持,使Flutter团队能够专注于使用范围更广的新平台。弃用意味着这些平台可能工作,但我们不会在这些平台上测试新版本的Flutter或插件。您可以在flutter.dev上看到目前支持的Flutter平台的列表。
总结
最后,一如既往地感谢世界各地的Flutter社区,是他们使这一切成为可能。对于在本次更新中贡献并审查了1000多个PR的数百名开发人员,为你们每个人的努力成果干杯。我们正在共同努力,为世界各地的开发者改变应用程序的开发过程,这样你就可以从一个代码库中更多、更快、更多地部署到你所关心的平台。
请继续关注我们在谷歌的Flutter团队的更多更新。这一年还没有结束!