全面了解Flutter

为什么Flutter选择使用Dart语言?

Flutter在四个主要维度进行了评估,并考虑了框架作者、开发人员和最终用户的需求等因素。我们发现不同的语言在不同的层面符合一部分需求,但Dart在所有评估维度上得分都很高,并且符合我们的所有要求和标准。

Dart运行时和编译器支持Flutter的两个关键特性的组合:基于JIT的快速开发周期:允许使用类型的语言进行形状更改和有状态的热重载;以及AOT编译器,可生成高效的ARM代码,可以快速启动并拥有可预测的生产部署性能。

此外,我们有机会与Dart社区密切合作,Dart社区正在积极投入资源改进Dart在Flutter中的使用。例如,当我们采用Dart时,该语言没有提供生成原生二进制文件的工具链(这对于实现可预测的高性能是很有帮助的),但是现在实现了,因为Dart团队为Flutter构建了它。同样,Dart VM之前已经针对吞吐量进行了优化,但团队现在正在优化VM的延迟时间,这对于Flutter的工作负载更为重要。

Dart在以下主要标准上得到高分:

  • 开发人员的效率。Flutter的主要价值主张之一是通过让开发人员使用相同的代码库为iOS和Android创建应用程序,从而节省了工程资源。使用高效的语言可以进一步加速开发周期,并使Flutter更具吸引力。这对我们的framework团队和开发人员都非常重要。大部分Flutter功能都是用Dart实现,因此我们需要在10万行代码时能保持高效的而不会牺牲framework和widget的可读性。
  • 面向对象。虽然我们可以使用非面向对象的语言,但这意味着要重新解决几个难题。另外,绝大多数开发人员都具有面向对象开发的经验,因此更容易学习如何使用Flutter进行开发。
  • 可预测,高性能。借助Flutter,我们希望使开发人员能够快速创建流畅的用户体验。为了实现这一点,我们需要能够在每个动画帧中运行大量的代码。这意味着我们需要一种既能提供高性能又能提供可预测性能的语言,而不会出现会导致丢帧的周期性暂停。
  • 快速内存分配。Flutter框架使用函数式流,它很大程度上依赖于底层的内存分配器,从而有效地处理小的、短期的内存分配会非常重要,所以在缺乏此功能的语言中Flutter无法有效地工作。

Flutter可以运行任何Dart代码?

Flutter能够运行大多数不会直接或间接导入dart:mirrors 或 dart:html的代码。

Flutter引擎有多大?

截止2017年6月,我们测量了一个最小的Android版Flutter应用程序(没有Material Components,只是一个Center构建的单个widget的应用)的大小,并将其打包为release版,大小约为6.7MB。

对于这个简单的应用程序,核心引擎大约3.3MB,框架+应用程序代码大约是1.25MB,LICENSE文件(包含在app.flx中)是55k,必需的Java代码.dex为40k,并且约有2.1MB的ICU数据。

当然,我们建议您测量自己的应用程序,通过运行flutter build apk然后查看app/outputs/apk/app-release.apk。

功能

Flutter应用程序性能如何?

Flutter应用程序性能非常出色。Flutter旨在帮助开发人员轻松实现恒定的60fps。Flutter应用程序通过本机编译的代码运行 - 不涉及解释器。这意味着Flutter应用程序可以快速启动并执行。

Flutter开发体验如何?编辑和刷新之间有多长时间?

Flutter实现了热重载开发循环。您可以在设备或模拟器上实现亚秒级重载。

Flutter的热重载是有状态的,这意味着应用程序状态在重载后仍然会保留。所以您可以在应用程序中各个页面快速迭代开发,而无需在每次重新加载后都要从主屏幕重新开始。

“热重载”与“完全重新启动”有何不同?

Hot Reload通过将更新的源代码文件注入正在运行的Dart VM(虚拟机)中工作。这不仅包括添加新类,还包括向现有类添加方法和字段,以及更改现有函数。尽管有几种类型的代码更改无法热重新:

  • 全局变量初始化器。
  • 静态字段初始化程序。
  • main()应用程序的方法。

请参阅使用Hot Reload获取更多详细信息。

Flutter支持哪些设备和操作系统版本?

移动操作系统:Android Jelly Bean,v16,4.1.x或更新的版本以及iOS 8或更新版本。

移动硬件:64位iOS设备(从iPhone 5S和更新的iPhone型号开始)以及ARM Android设备。

请注意,我们目前不支持:

  • ARM32 iOS设备(iPhone 4,iPhone 5;问题#2089)
  • x86 Android设备(问题#9253)

我们支持使用Android和iOS设备(包括Android模拟器和iOS模拟器)来开发测试Flutter应用。

我们测试了各种低端到高端手机,但我们还没有官方设备兼容性保证。

我们不会在平板电脑上进行测试,因此平板电脑上的某些widget可能会出现问题。我们尚未在我们的widget中实施针对平板电脑的改动。

Flutter是否可以在web上运行?

不,我们不是在提供Flutter的web版本。

我可以使用Flutter构建桌面应用程序吗?

我们专注于移动端优先。但是,Flutter是开源的,我们鼓励社区以各种有趣的方式使用Flutter。

我可以在我现有的原生应用程序中使用Flutter吗?

可以,您可以在现有的Android或iOS应用中嵌入Flutter,但是我们的工具目前尚未完全针对此用例进行优化(请参阅此问题以了解详细信息)。

目前的两个示例是platform_view 和flutter_view 示例。一些开始文档可以在wiki页面中 添加Flutter到现有的应用程序。

我可以访问平台服务和API,如传感器和本地存储吗?

可以。Flutter为开发人员对操作系统中某些平台特定服务和API提供了访问支持,但是为了尽可能多的功能通用,Flutter本身不会提供太多特定于平台的动能,您可以使用平台通道自己定制。

许多平台服务和API都在Pub仓库中提供了现成的软件包。使用现有的软件包非常简单。

最后,我们鼓励开发人员使用Flutter的异步消息传递系统与平台和第三方API创建自己的集成。开发人员可以根据需要公开尽可能多的平台API,并构建最适合他们项目的抽象层。

我可以扩展和自定义widget吗?

当然可以!Flutter的widget系统被设计为易于定制的,而不是让每个widget提供大量的参数。Flutter拥抱组合:widget由较小的widget构建而成,您可以以各种方式组合,以制作自定义widget。例如,RaisedButton将一个Material widget与一个GestureDetector widget组合在一起,而不是对一个通用按钮widget进行子类化。Material widget提供了可视化设计,而GestureDetector widget提供了交互设计。

要使用自定义视觉设计创建按钮,可以将实现视觉设计的widget与提供交互设计的GestureDetector结合使用。例如,CupertinoButton遵循这种方法,将GestureDetector与其他几个实现其视觉设计的widget结合在一起。

组合可以最大限度地控制widget的视觉和交互,同时还可以重复使用大量的代码。在框架中,我们已经将复杂的widget分解为各个部分,分别实现视觉、交互和动画设计,您可以将这些widget重新组合。

为什么要在iOS和Android上共享布局代码?

您可以选择为iOS和Android实现不同的应用布局。开发人员可以在运行时检查移动操作系统并呈现不同的布局,但我们发现这种做法很少见。

我们看到越来越多的移动应用布局和设计发展为品牌优先的跨平台统一的风格。这意味着在iOS和Android上共享布局和UI代码的意愿非常强烈。

与严格遵守传统平台美学相比,应用程序美学设计的品牌标识和定制现在变得越来越重要。例如,应用程序设计通常需要自定义字体、颜色、形状、动作效果等以清楚地表达其品牌标识。

我们还可以看到在iOS和Android上通用的布局模式。例如,现在可以在iOS和Android上自然找到“底部导航栏”模式。移动平台似乎有设计思想的融合。

可以与移动平台的默认编程语言进行交互吗?

可以,Flutter支持与原生之间通过platform channels进行功能互调,这是通过灵活的消息传递模式支持的。

Flutter是否带有reflection/mirrors系统?

目前还没有。由于Flutter应用程序是针对iOS预编译的,并且二进制大小始终是移动应用程序关注的问题,因此我们禁用了reflection/mirrors 。我们很好奇您可能需要反射/镜像的场景 - 请通过flutter-dev@googlegroups.com与我们联系。

如何在Flutter中进行国际化(i18n)、本地化(l10n)和实现辅助功能(a11y)?

Flutter内置了对基本辅助功能的支持,包括Android和iOS上的屏幕阅读器。查看语义 widget,了解如何自定义Flutter应用的辅助功能。

我们鼓励您将有关这些功能的问题通过电子邮件flutter-dev@googlegroups.com 发给我们。

如何为Flutter编写并行/并发应用程序?

Flutter支持isolates。isolates是Flutter虚拟机中的独立堆,它们可以并行运行(通常作为单独的线程实现)。isolates通过发送和接收异步消息进行通信。虽然我们正在为此评估解决方案,但Flutter目前还没有共享内存并行解决方案。

查看一个在Flutter中使用isolates的例子。

我可以在Flutter应用程序的后台运行Dart代码吗?

由于在Android和iOS平台上支持后台执行的基本差异,在后台运行代码具有特定于平台的API。

在Android上,android_alarm_manager 即使您的Flutter应用程序不在前台,该插件也可让您在后台运行Dart代码。

在iOS上,我们目前不支持此功能。请留意Bug 6192的更新。

我可以在Flutter中使用JSON / XML / protobuffers…吗?

当然可以!在pub.dartlang.org中有处理JSON、XML、protobufs和许多其他格式的库。

有关如何在Flutter中使用JSON的教程,请参阅JSON教程。

我可以使用Flutter构建3D(OpenGL)应用程序吗?

我们暂时不支持OpenGL ES或类似的3D。长期有计划支持,但现在我们专注于2D。

为什么我的APK或IPA如此之大?

通常,资源包括图像、声音文件、字体等,这些是APK或IPA的大部分。Android和iOS生态系统中的各种工具可以帮助您了解APK或IPA中的内容。

此外,请务必使用Flutter工具创建APK或IPA的发布版本。发布版本通常小于调试版本。

详细了解如何创建 Android发布版本,以及如何创建iOS应用发布版本。

Flutter应用是否在Chromebook上运行?

我们看到Flutter应用在某些Chromebook上运行。我们正在跟踪 与在Chromebook上运行Flutter相关的问题。

Framework

为什么build()方法在State(而不是StatefulWidget)上?

将 Widget build(BuildContext context)方法放在State上而不是StatefulWidget上是为了在继承StatefulWidget时能更加灵活,您可以阅读 API文档中关于State.build的详细讨论。

Flutter的标记语言在哪里?为什么Flutter没有标记语法?

我们发现使用代码动态构建的UI会更灵活。例如,我们发现严格的标记系统难以表达和生成具有特定行为的widget。我们还发现,我们的“代码优先”更好地支持热重载和动态环境适应等功能。

当然也可以创建一个自定义标记语言,然后将其动态的转化为dart代码。

应用在右上角有一个“Slow Mode”横幅,为什么看到这个?

默认情况下,flutter run命令会使用调试版本配置。

调试配置在虚拟机中运行Dart代码,通过热重载实现快速开发周期(发布版本使用标准Android和iOS 工具链进行编译)。

调试配置还会检查所有断言,这有助于在开发过程中尽早发现错误,但会增加运行时成本。“Slow Mode”横幅表示启用了这些检查。您可以使用--profile或--release参数来通过flutter run 命令运行应用程序,这会关闭这些检查,如果您正在使用IntelliJ的Flutter插件,则可以通过Run> Flutter Run in Profile Mode 或Release Mode

Flutter框架使用什么编程范式?

Flutter是一个多范式编程环境。在Flutter中使用了过去几十年中开发的许多编程技术。我们使用的每一个范式都是我们相信该它的优势特别适合Flutter:

  • 组合:Flutter使用的主要范例是使用小对象,然后将它们组合在一起以获得更复杂的对象。Flutter widget库中的大多数widget都是以这种方式构建的。例如,Material FlatButton 类是使用MaterialButton 类构建, 该类本身使用IconTheme、InkWell、Padding、Center、Material、AnimatedDefaultTextStyle和ConstrainedBox组合 构建。该InkWell 使用内置GestureDetector。Material 是使用内置AnimatedDefaultTextStyle、NotificationListener和AnimatedPhysicalModel。等等,它们都是widget。
  • 函数式编程:整个应用程序可以仅使用StatelessWidget来构建 ,这些函数本质上是描述参数如何映射到其他函数的函数。在计算布局或绘制图形的底层(这些应用程序不拥有状态,因此通常是非交互式的)例如,Iconwidget本质上是一个将其参数(颜色、 icon、size)映射到布局基本单元的函数。此外,大量使用的是不可变数据结构,包括整个Widget类层次结构以及许多支持类,如 Rect和 TextStyle也都是。Dart中的Iterable API经常用来处理框架中的值列表,它大量使用了函数式(map,reduce,where等)方法。
  • 事件驱动:用户交互由事件对象表示,这些事件对象被分派给注册了事件处理程序的回调。屏幕刷新也由类似的回调机制触发。监听类是动画系统的基础,它确立了与多个监听事件订阅模式。
  • 基于类的面向对象编程:框架的大部分API都是使用继承类来构建的。我们使用一种方法来在基类中定义非常抽象的API,然后在子类中迭代地对它们进行定制化。例如,我们的渲染对象有一个与坐标系无关的基类(RenderObject),然后我们有一个子类(RenderBox),它引入了基于笛卡尔坐标系(x / width)和Y /高度)。
  • 基于原型的面向对象编程: ScrollPhysics 类将实例链接起来组成适用于在运行时动态滚动的physics。这使得系统可以编写包含特定平台physics的分页physics,而无需在编译时选择平台。
  • 命令式编程:直接命令式编程通常与对象内部封装的状态配对,用于提供最直观的解决方案。例如,测试是以一种强制性风格编写的,首先描述测试中的情况,然后列出测试必须匹配的不变量,然后根据测试需要推进时钟或插入事件。
  • 响应式编程:widget和元素树有时被描述为响应式的,因为在widget的构造函数中提供的新输入会立即作为widget的构建方法对较低级别widget的更改传播,并在较低widget中进行更改(例如,作为响应到用户输入)通过事件处理程序传播回widget树。根据widget的需求,功能向应和命令响应两方面都存在于框架中。具有构建方法的widget仅由一个表达式组成,该表达式描述了widget如何对其配置中的变化做出反应的功能响应widget(例如,Divider类)。 构建方法通过几个语句构建子项列表的widget,描述了widget如何对其配置中的更改作出反应,这些都是命令性响应widget(例如 Chip类)。
  • 声明式编程:widget的构建方法通常是具有多层嵌套构造函数的单一表达式,使用Dart的严格声明子集编写。这样的嵌套表达式可以机械地转换成任何适合表达的标记语言或从任何适合表达的标记语言转换。例如,UserAccountsDrawerHeader widget具有很长的构建方法(20行以上),由单个嵌套表达式组成。这也可以与命令式风格相结合来构建用纯粹声明式方法难以描述的UI。
  • 泛型:类型可用于帮助开发人员及早发现编程错误。Flutter框架使用泛型编程来处理这个问题。例如, State类根据其关联widget的类型进行参数化,以便Dart分析器可以捕获状态和widget的不匹配。类似地, GlobalKey类需要的类型参数,以便它可以访问远程widget的状态下在一个类型安全的方式(使用运行时检查), 路由接口是参数化时,它是预期使用类型 pop和集合,例如List、Map和 Set都是参数化的,这样可以在分析过程中或在调试期间的运行时提前捕获不匹配的元素。
  • 并发:Flutter大量使用 Future和其他异步API。例如,动画系统通过Future来完成动画完成时的通知。图像加载系统同样使用Future在加载完成时进行报告。
  • 约束:Flutter中的布局系统使用弱形式的约束编程来确定场景的几何形状。约束(例如,对于笛卡尔盒子,最小和最大宽度以及最小和最大高度)从父母传递给孩子,并且孩子选择生成的几何结构(例如,对于笛卡尔盒子,大小,特别是宽度和高度)满足这些限制。通过使用这种技术,Flutter通常可以通过一次遍布整个场景。

项目

我在哪里可以获得支持?

如果您认为遇到了错误,请将反应到我们的[issue](https://github.com/flutter/flutter/issues中总。我们鼓励您使用Stack Overflow来处理“HOWTO”类型的问题。有关讨论,请加入我们的邮件列表 flutter-dev@googlegroups.com

Flutter是开源的吗?

是的,Flutter是开源技术。你可以在GitHub上找到这个项目。

我如何参与Flutter项目?

Flutter是开源的,我们鼓励你贡献。您可以先简单地提交功能请求和错误issue

我们建议您加入我们的邮件列表 flutter-dev@googlegroups.com,并告诉我们您如何使用Flutter以及您想如何使用它。

如果您对提供代码感兴趣,可以先阅读我们的 “参与指南” 并查看我们的轻松入门issue列表 。

哪些软件许可证适用于Flutter及其依赖项?

Flutter包含两个组件:一个作为动态链接二进制文件发布的引擎和作为引擎加载的单独二进制文件的Dart framework。该引擎使用多个具有许多依赖关系的软件组件; 在这里查看完整列表。

该framework完全独立,只需要一个许可证。

另外,您使用的任何Dart软件包可能都有自己的许可证要求。

我如何确定我的Flutter应用程序需要显示的许可证?

有一个API可以找到您需要显示的许可证列表:

  • 如果您的应用程序具有Drawer,请添加一个AboutListTile。
  • 如果您的应用程序没有一个Drawer但使用Material组件库,调用其中showAboutDialog或showLicensePage。
  • 对于自定义的方法,您可以从LicenseRegistry获取原始许可证。

谁在用Flutter工作?

Flutter是一个开源项目。目前,大部分的开发工作都是由Google的工程师完成的。如果您对Flutter感到兴奋,我们鼓励您加入社区并为Flutter做出贡献!

Flutter的指导原则是什么?

我们相信:

  • 为了覆盖每个潜在用户,开发人员需要针对多个移动平台。
  • HTML和WebViews在一直存在着性能短板,如由于滚动、连续点击等体验都不是很好,
  • 今天,多次构建相同应用程序的成本太高:它需要不同的团队,不同的代码库,不同的工作流程,不同的工具等。
  • 开发人员希望使用一个简单的代码库来为多个目标平台构建移动应用程序,他们不想牺牲质量、控制和性能。

我们专注于三件事情:

  • 控制 - 开发人员应该可以访问和控制系统的所有层。这导致:
  • 性能 - 用户应该拥有完美的流畅、响应快、jank-free的应用程序。
  • 精细 - 每个人都值得拥有精细、美观、愉快的移动应用体验。

苹果是否会拒绝我的Flutter应用程序?

我们不能为苹果公司发言,但多年来苹果的政策已经发生了变化,他们允许使用Flutter等系统构建的应用程序。我们看到使用Flutter构建的应用程序已经通过App Store进行了审查和发布。

当然,Apple最终负责他们的生态系统,但我们的目标是继续尽我们所能确保Flutter应用程序可以部署到Apple的App Store中。

想学习更多Android知识,或者获取相关资料请加入Android技术开发交流2群:862625886。 有面试资源系统整理分享,Java语言进阶和Kotlin语言与Android相关技术内核,APP开发框架知识, 360°Android App全方位性能优化。Android前沿技术,高级UI、Gradle、RxJava、小程序、Hybrid、 移动架构师专题项目实战环节、React Native、等技术教程!架构师课程、NDK模块开发、 Flutter等全方面的 Android高级实践技术讲解。还有在线答疑

代码交流 2021