Flutter 和桌面應用的最新進展

作者 / 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 的桌面支持一直是最受期待的新功能之一。未來數週內,我們將爲大家帶來更多這方面的進展;同時,我們認爲有必要先展示來自各個產品功能團隊的成果 (這些成果最終會整合進完整的項目中),並蒐集大家的反饋。雖然桌面支持目前已推出技術預覽版本,但我們仍然有大量工作需要完成。

發佈模式

繼 macOS 之後,我們還爲 Flutter 增加了 WindowsLinux 系統的 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)、舒適 (comfortable)、標準 (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<Utf16> lpText, Pointer<Utf16> lpCaption, Int32 uType);
typedef MessageBoxDart = int Function(
    int hWnd, Pointer<Utf16> lpText, Pointer<Utf16> lpCaption, int uType);


final user32 = DynamicLibrary.open('user32.dll');
final win32MessageBox =
    user32.lookupFunction<MessageBoxNative, MessageBoxDart>('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

△ 通過 Dart 代碼調用 Win32 MessageBox API

  • 完整示例

    https://gist.github.com/timsneath/181092c75864001ca37b1b1495b9b396

在上例中,我們通過兩個 typedef 分別體現了方法的原生和 Dart 版本形式。完成這些定義後,我們便可通過 lookupFunction() 方法加載 Windows 動態鏈接庫 (DLL),lookupFunction() 負責將方法簽名映射到底層的原生入口,DLL 則負責提供方法的實現。最後,我們可以選擇添加一個簡單的慣用包裝器,使其便於從其他 Dart 代碼進行訪問,運行結果如下:

△ 使用 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 等遊戲引擎。這種特定於平臺的容器應用負責提供入口,與底層操作系統進行協調以使用表面渲染、無障礙功能和輸入等服務,並管理消息事件循環。

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,這是一款針對德國教育市場的學生管理應用,最初創建的是移動應用版本,但最近增加了網頁和桌面版本。

△ Sharezone Schulplan: 一款面向學生、教育工作者和家長的應用,用於跟蹤家庭作業、學習小組和課程表等情況

  • Sharezone

    https://sharezone.net/

在接下來的數週裏,我們將分享更多關於桌面支持的信息;同時,我們也期待着聽到您的反饋。如果您是插件作者,我們建議您開始評估將自己的插件適配至即將到來的這些桌面平臺所需要的開發工作;如果您已發佈應用,不妨嘗試將應用作爲桌面應用運行,並告訴我們您的運行情況。

您是否願意體驗 Flutter 的桌面應用?歡迎在下方評論區說出您的想法。


推薦閱讀




 點擊屏末  | 訪問 Flutter 開發者社區中文資源


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章