![8c864848185bf3d4de3a4f9fc79dc9eb.png](https://i-blog.csdnimg.cn/blog_migrate/546fec3d4602f10a01cf2cf41a39137b.jpeg)
作者 / Tim Sneath, Product Manager for Flutter and Dart, Google
众所周知,在开发 Flutter 时,我们希望通过单一代码库支持 Flutter 在各类设备 (包括 iOS、Android、Windows、Linux、macOS 和 Web) 上的应用,并实现原生编译和游戏级别的视觉效果。Flutter 也已经在 Google 内部广泛用于 Assistant、Stadia、Cloud Search 以及 Blogger 等项目。在 Google 之外,字节跳动、Grab、Nubank 以及 MGM Resorts 等公司也都已采用 Flutter,并通过 Flutter 提升了生产力和灵活性。
很多人都想了解 Flutter 在桌面操作系统 (包括 Windows、macOS 和 Linux) 上的进展: 据调查和 GitHub 数据显示,Flutter 的桌面支持一直是最受期待的新功能之一。未来数周内,我们将为大家带来更多这方面的进展;同时,我们认为有必要先展示来自各个产品功能团队的成果 (这些成果最终会整合进完整的项目中),并搜集大家的反馈。虽然桌面支持目前已推出技术预览版本,但我们仍然有大量工作需要完成。
![25194d6195cdc27c566200e787efe2fe.png](https://i-blog.csdnimg.cn/blog_migrate/a343f84578048ee1520de710a18e9ee5.jpeg)
发布模式
继 macOS 之后,我们还为 Flutter 增加了 Windows 和 Linux 系统的 Profile Mode (性能模式) 和 Release Mode (发布模式) 。例如,如果您运行的是最新版 Flutter,现在可以使用 flutter build windows 命令,将 Flutter 应用编译为 Windows 可执行文件。此操作使用我们在生产环境中的 AOT 编译器来创建原生 x64 机器代码,而这些代码可分发至那些未安装 Flutter 的设备上。
- Windows 发布模式
https://github.com/flutter/flutter/issues/38477
- Linux 发布模式
https://github.com/flutter/flutter/issues/38478
- AOT 编辑器
https://en.wikipedia.org/wiki/Ahead-of-time_compilation
桌面级体验
无论您要构建的是独立可执行文件还是 Web 应用,桌面级体验都有其独特的属性: 桌面窗口通常采用横屏模式并可以调整大小、输入通常由物理键盘和鼠标完成,而不是通过屏幕键盘和触摸操作,同时,控件也是基于不同的屏幕内容密度进行的优化。
在框架层面,我们对 Flutter 进行了多项变更以支持桌面级体验。
- 在最新版本 Flutter 中创建新项目时,您会看到默认模板包含了对 visualDensity 属性的引用,该属性允许控件根据目标平台调整其密度,从而在桌面平台上实现更紧凑的间距。其中一个例子就是 TextField: 它可根据指定的密度提供紧凑 (compact)、舒适 (compact)、标准 (standard) 三种间距。
- 我们优化了对鼠标和键盘输入的支持,其中包括 Windows 上的原始键代码、鼠标右键操作、光标更改和滚轮支持。
- 您现在可以 (通过 Platform 类) 查询特定平台,Windows、macOS 和 Linux 平台均可提供恰当的查询结果。
- 我们在最新版本中添加了一个 NavigationRail widget,该 widget 专为在桌面设备和平板电脑上打造桌面级体验而设计。
- visualDensity
https://api.flutter-io.cn/flutter/material/ThemeData/visualDensity.html
- 桌面端需要更高的屏幕内容密度
https://github.com/flutter/flutter/issues/43350
- TextField
https://api.flutter-io.cn/flutter/material/TextField-class.html
- 为 TextField 实现 visualDensity
https://github.com/flutter/flutter/pull/51438
- 在 Windows 上实现键盘映射
https://github.com/flutter/flutter/issues/52264
- 支持光标更改
https://github.com/google/flutter-desktop-embedding/issues/376
- NavigationRail widget
https://api.flutter-io.cn/flutter/material/NavigationRail-class.html
外部函数接口
Dart 团队一直在努力完善外部函数接口 (Foreign Function Interface, FFI) ,以加速平台集成的进程。对于基于 C 语言的 API,dart:ffi 库提供了一种直接绑定到原生代码的机制;Dart 运行时则提供了在 Dart 对象支持的堆上分配内存并调用动态链接库的功能。
- 通过 dart:ffi 实现 C 语言互操作
https://dart.cn/guides/libraries/c-interop
以下代码片段为 Windows 系统环境中的一个简单示例,该示例完全使用 Dart 代码来调用传统的 Win32 MessageBox() API:
typedef MessageBoxNative = Int32 Function( IntPtr hWnd, Pointer lpText, Pointer lpCaption, Int32 uType);typedef MessageBoxDart = int Function( int hWnd, Pointer lpText, Pointer lpCaption, int uType);final user32 = DynamicLibrary.open('user32.dll');final win32MessageBox = user32.lookupFunction('MessageBoxW');void showMessageBox(String message, String caption) => win32MessageBox( 0, // No owner window Utf16.toUtf16(message), // Message Utf16.toUtf16(caption), // Window title 0 // OK button only );…showMessageBox('Test Message', 'Window Caption'); // call just like any other Dart function
- 完整示例
https://gist.github.com/timsneath/181092c75864001ca37b1b1495b9b396
在上例中,我们通过两个 typedef 分别体现了方法的原生和 Dart 版本形式。完成这些定义后,我们便可通过 lookupFunction() 方法加载 Windows 动态链接库 (DLL),lookupFunction() 负责将方法签名映射到底层的原生入口,DLL 则负责提供方法的实现。最后,我们可以选择添加一个简单的惯用包装器,使其便于从其他 Dart 代码进行访问,运行结果如下:
![f9d25bccbd187c444decd7978112df1d.png](https://i-blog.csdnimg.cn/blog_migrate/bba2898ea4658ed0475728b044234ac7.jpeg)
△ 使用 Win32 MessageBox API 的 Windows 简单示例应用
当然,您不必亲自完成这项工作: 有人很可能已经处理好了您要使用的 API。您可以阅读我们的官方文档,详细了解如何在 Flutter 中使用 FFI。
- 访问常用 Win32 API 的 Dart
https://pub.flutter-io.cn/packages/win32
- 官方文档: 使用 dart:ffi 调用原生代码
https://flutter.cn/docs/development/platform-integration/c-interop
更新插件模型
从设计上说,Flutter 本身的核心很小。Flutter 并没有在框架中提供海量内容,而是通过插件和 package (无论是直接来自 Flutter 团队还是来自更广泛的生态系统中的贡献者) 来实现与底层操作系统的集成。
但是,随着 Flutter 对移动设备、Web 和桌面端的支持日益增多,为每个目标平台开发插件也变得越来越具有挑战性。更可能出现的情况是: 一个插件需要多个掌握各自平台专业知识的作者通力合作,才能完成开发。
一个可行的做法是,在核心插件中定义出通用接口,并在各个平台上独立完成具体的实现。因此,正如近期一篇关于现代插件开发的博文所述,我们最近对插件的架构进行了调整,使多个作者能够更加轻松地合作完成各个平台的开发。基于目前的进展,插件现在可以明确地声明其所支持的具体平台。
- 博文: 现代 Flutter 插件开发
https://medium.com/flutter/modern-flutter-plugin-development-4c3ee015cf5a
- 指定插件所支持的平台
https://flutter.cn/docs/development/packages-and-plugins/developing-packages#plugin-platforms
我们已经开始使用此模型来构建一些核心插件,您也可以在 flutter/plugins repo 中找到一些基于这个联合开发模型的早期示例。
- flutter/plugins repo
https://github.com/flutter/plugins/tree/master/packages/path_provider
请注意,Windows 和 Linux 插件 API 仍在开发之中,因此,虽然我们鼓励大家多多探索,但目前尚未准备好用于通用生产环境。我们也致力于在 pub.dev 上添加桌面平台标签。
在 Windows 上运行: Win32 和 UWP
在 Windows 上进行开发有一个很有趣的点在于,我们会试验各种架构方法。在任何平台上,Flutter 应用其实都是内嵌于一个很小的容器应用 (即 "embedder") 中的,这种做法类似 Unity 等游戏引擎。这种特定于平台的容器应用负责提供入口,与底层操作系统进行协调以使用表面渲染、无障碍功能和输入等服务,并管理消息事件循环。
![94bb8f4d74c5076207c4a9a8300da03a.png](https://i-blog.csdnimg.cn/blog_migrate/12a33e9e3168ee51363a852851d894b0.jpeg)
Windows 提供了两种不同的方法来创建这个容器应用。第一个是使用成熟的 Win32 编程模型来创建 Flutter 内容的入口;这为 Windows 7 等平台提供了最大的向后兼容性,同时能构建出符合诸多开发者预期的标准 EXE 文件。第二个则是现代 UWP 应用模型,推荐在 Windows 10 上使用。这种方法拥有更广阔的想象空间,比如能够帮助开发者将 Flutter 支持扩展至 Xbox 等设备或即将推出的 Windows 10X 操作系统。
- Windows 10X
https://docs.microsoft.com/en-us/dual-screen/windows/get-dev-tools
我们一直与多位社区贡献者一起探讨本文所述的不同解决方案。同时我们很期待与微软紧密合作,共同完成高质量的解决方案。Surface 系列设备正不断扩展,现在其产品已涵盖 Android 和 Windows。我们认为 Flutter 可为微软提供非常有吸引力的平台,横跨其全部产品阵容并提供卓越的原生体验。
尽情探索桌面体验
桌面体验目前仍处于技术预览版状态,而 API 和工具尚不稳定。在将桌面支持升级到稳定版本之前,我们仍将持续跟进大量需要完成的必要工作,包括改进无障碍功能和本地化支持。
如果您想要试用,则需要使用开发版本。Windows 和 Linux 支持目前仅在 master 渠道上可用,我们也在这个渠道中积极进行着 Flutter 的开发。macOS 在 dev 渠道上可用,虽然稳定性较好,但不建议用于生产环境。您可以在 Flutter master 渠道或 dev 渠道之间进行切换,然后使用以下任一命令来为您使用的平台提供支持:
C:flutter> flutter config --enable-windows-desktop$ flutter config --enable-macos-desktop$ flutter config --enable-linux-desktop
一些积极探索的开发者已经 "尝鲜",在桌面环境中利用 Flutter 创建应用。我们见证的首批 Flutter macOS 桌面应用便包括 Sharezone,这是一款针对德国教育市场的学生管理应用,最初创建的是移动应用版本,但最近增加了网页和桌面版本。
![34c65b5486001edb6474b9f08fdaa4fa.png](https://i-blog.csdnimg.cn/blog_migrate/c405573e28a4871eadd9d7cd09b8c206.jpeg)
△ Sharezone Schulplan: 一款面向学生、教育工作者和家长的应用,用于跟踪家庭作业、学习小组和课程表等情况
- Sharezone
https://sharezone.net/
在接下来的数周里,我们将分享更多关于桌面支持的信息;同时,我们也期待着听到您的反馈。