這會是一篇幫你深入理解 Flutter 真正優勢的內容,同時也解釋了:為什麼 Flutter 在鴻蒙這個全新平台上適配可以完成得那麼快。
內容較長,不建議 AI 總結。
其實,一直以來 Flutter 的最大的優勢都不是它的上層 UI,而是它的底層 Embedder,就像 KMP 最大的優勢是 Kotlin 的強大的編譯器支撐一樣,Flutter 的最大價值其實是它的 Flutter Embedder:通過 Embedder 你可以在任何「非官方」平台跑起來 Flutter。
這也是為什麼 Flutter 會是鴻蒙最早發布的跨平台框架,這也是為什麼「寶馬」和「豐田」可以在自家車機系統使用 Flutter、LG 的 WebOS 電視系統可以使用 Flutter、Raspberry Pi(樹莓派)和三星 Tizen 等 IoT 也使用 Flutter 的根本原因。
當然,這個場景對於一般的應用開發者來說難度較高,因為 Embedder 的 API 雖然穩定,但 API 很底層,不適合新手直接從零開始,所以它更多體現在企業價值,比如最近的豐田進一步開發 Flutter,推出全新 3D 遊戲引擎 Fluorite這種情況,它的價值在於為企業提供一套成熟的可遷移渲染架構支持。
那所謂的 Flutter Embedder 它到底“嵌入”了什麼?
簡單來說,Flutter 的 Engine 通常以動態庫形式交付,而對外提供一個穩定 ABI 的 C 接口,所以真正把 Flutter 跑起來的,是平台側那層很薄的 Embedder,你可以這麼理解:
Flutter Engine:Dart VM + 渲染管線(Skia/Impeller 等)、文本排版、動畫、合成、語義(無障礙)等「UI 引擎本體」
Embedder:負責把引擎接到真正的設備層,包括圖形上下文/交換鏈、輸入事件、VSync、線程模型、文件與資源、平台消息通道(platform channel)、可選的外部紋理/原生視圖合成等。
為了確保 Embedder 與 Engine 版本之間的解耦,Flutter 定義了一套嚴格的 ABI 規則,所有的配置信息通過
embedder.h中的結構體進行傳遞,而這些結構體的新成員只能添加在末尾,且每個結構體的第一個成員必須是size_t struct_size的存在,這種設計讓 Engine 可以在運行時根據傳入的大小判斷 Embedder 支援的 API 版本,從而實現向前和向後兼容。

那麼如果使用 Embedder 層,一般需要做什麼?為什麼說它對新手難度比較高?簡單來說,Flutter 的 Embedder 可以按能力分成 6 個部分來理解。
核心是 FlutterEngineRun(...),它是通用的嵌入層入口,開發者要提供 FlutterRendererConfig(渲染後端配置)和 FlutterProjectArgs(資源、回調、快照等)來滿足 Flutter 運行的環境,例如 FlutterProjectArgs 裡最常見是:
assets_path:Flutter 資源目錄icu_data_path:icudtl.dat(國際化/文字相關)platform_message_callback:平台消息回調另外就是如何把 Flutter 畫到屏幕上,FlutterRendererConfig 支援多種後端:OpenGL / Vulkan / Metal / Software,一般在第三方平台,最常見的就是 OpenGL,對於 OpenGL 會需要實現一組回調:
make_current / clear_current:切換/清理上下文fbo_callback:告訴引擎往哪個 FBO 畫present 或 present_with_info:提交到屏幕(可帶 damage 信息做局部刷新優化)make_resource_current:給後台線程的資源上下文(紋理異步上傳性能很關鍵)如果還要做更高級的合成(比如硬體 overlay plane、原生視圖/多層合成),還會用到 compositor(
FlutterCompositor)接口:引擎把 layer 信息交給平台,平台負責最終上屏合成。
當然,鴻蒙平台現在也已經實現了 Vulkan + Impeller 的默認支援。
如果對應平台,類似嵌入式里經常沒有現成的消息循環模型或者多線程模型,開發者就要提供自己實現的自定義 task runner:
FlutterTaskRunnerDescription:至少要實現 post_task_callbackFlutterCustomTaskRunners:可分別指定 platform / render task runner(也可以合併到同一線程)這部分決定了 Flutter 能否穩定跑在設備的主循環(systemd event loop、glib、Qt event loop、裸循環等)上。
Flutter 引擎還需要在平台 VSync 同步信息來時通知 FlutterEngineOnVsync(...),並且有明確線程要求(必須在調用 FlutterEngineRun 的線程上),沒有正確 VSync,你可能會遇到:
這個在一些嵌入式平台確實會有這個問題,所以需要開發者自己處理。
Embedder 還需要把設備輸入轉成 Flutter 的事件並送入引擎,例如:
SendPointerEvent(觸摸/滑鼠)SendKeyEvent(鍵盤)SendWindowMetricsEvent(大小、devicePixelRatio 變化等)其他的主要看你是否有哪些對應的需要,例如:
Platform Channels 交互實現,通過 Platform Channels 把 Dart 端的調用轉成平台端實現(例如電量、藍牙、相機等),在嵌入平台你一樣可以用 platform channels 去封裝 native 能力,在 embedder C API 裡對應的是:
platform_message_callback 接收來自 Dart 的消息FlutterEngineSendPlatformMessageResponse(...)外部紋理(External Texture),通常是用於視頻流/相機/解碼器/硬體圖層等,例如:
FlutterEngineRegisterExternalTextureFlutterEngineMarkExternalTextureFrameAvailableFlutterEngineUnregisterExternalTexture無障礙/語義(Semantics),FlutterProjectArgs 裡有語義更新回調,引擎也有啟用/派發語義動作的接口(用於屏幕閱讀、無障礙輸入等)
簡單總結一下,大致有:
| API 類別 | 關鍵函數/結構體 | 平台對接職責 |
|---|---|---|
| 生命週期管理 | FlutterEngineRun, FlutterEngineShutdown |
控制引擎的啟動時機與資源回收 |
| 渲染配置 | FlutterRendererConfig |
指定 OpenGL、Vulkan 或軟體渲染的回調函數 |
| 消息傳遞 | FlutterEngineSendPlatformMessage |
實現 Dart 與原生代碼的雙向異步通信 |
| 事件注入 | FlutterEngineSendPointerEvent |
將硬體層產生的觸摸/滑鼠事件轉換為 UI 事件 |
| 任務調度 | FlutterTaskRunnerDescription |
定義任務發布回調,將引擎任務整合進系統事件循環 |

所以,可以看出,從 0 實現一個 Embedder 的工作量還是不小的,但是也可以看出,在這個過程中,你只需要專注於 如何用 Embedder 接口讓 Flutter 成功運行起來,不需要關心 Engine 和 Framework 的相關實現,況且,也沒有讓你真的從 0 開始寫。
比如你需要在嵌入式設備上實現 Embedder,而嵌入式上系統大多數時候都是精簡的 Linux 魔改,那麼你完全可以基於 Linux embedded 稍微調整來實現對接即可,比如 flutter-pi 和 Sony 的 flutter-embedded-linux 方向:
flutter-pi就是 “輕量 Linux Embedded embedder、無需 X11/Wayland”,這種直接渲染模組(DRM)和通用緩衝管理(GBM)實現,通過“直接入屏”的渲染路徑跳過了 X11 或 Wayland 等合成器,可以降低顯存佔用和顯示延遲,非常適合一些嵌入式場景。
Flutter 的 Embedded Linux 就是目前被二次定製最多的 Embedded,特別是它已經有的:
比如鴻蒙內核,它的內核是兼容 Linux 的,基礎三大件:
我們假設不是手機鴻蒙,而是 OpenHarmony,在沒有官方支援的情況下,也可以通過 Linux Embedded 去嘗試接入 Flutter。
當然,如果需要運行的平台真的很特殊,你需要從頭開始,那麼實現路線也很清晰:
libflutter_engine.so/類似動態庫 + icudtl.dat 等),一般這種情況下就需要你自己編譯 enginelibdrm 打開顯示節點,通過 libgbm 創建緩衝區,並初始化 EGL Surface,建立 swapchain / framebuffer / surface,實現 FlutterRendererConfig 對應回調和配置TaskRunners,實現一個基於 epoll 或 glib 的消息循環,當 Flutter Engine 有任務需要執行時,通過 post_task_callback 通知啟動器,啟動器需將該任務排入系統事件隊列libinput 或驅動,實時獲取事件並調用 FlutterEngineSendPointerEvent在這方面三星 Tizen 系統的集成也是一個很好的例子,flutter-tizen 的 Embedder 實現,讓開發者能夠利用同一套代碼給三星的電視、冰箱屏幕甚至手錶開發應用。
當然,要說 Flutter 嵌入層最成功的典型例子,那肯定是鴻蒙 Flutter:華為實現的 flutter_flutter 現在已經有 3.35.7的 dev 分支,也就是 framework 和 engine 已經完全合併的 Monorepo,項目在標準 Flutter 倉庫的基礎上進行了擴展,具體包括:
engine/src/flutter/shell/platform/ohos/ 的 C++ OHOS 平台 shellengine/src/flutter/shell/platform/ohos/flutter_embedding/ 的嵌入實現packages/flutter_tools/ 中的 OHOS 特定構建命令bin/internal/engine.ohos.version 和 bin/internal/engine.ohos.har.version首先我們前面說的 FlutterEngineRun 是通用 Embedder API,在鴻蒙上會通過 ArkTS -> NAPI -> native 路徑調用,而 FlutterRendererConfig 在鴻蒙上與 XComponent 強綁定,由 XComponentBase 實現具體渲染回;FlutterProjectArgs 中的資源路徑、AOT 數據、任務運行器等會結合鴻蒙文件系統與線程模型配置,通過 FlutterNapi 將 ArkTS 層配置轉換為 native 層 FlutterEngineRun 所需參數:

具體層級關係如下圖所示:

在這裡,Embedding 的實現具體有:
FlutterAbility 繼承自鴻蒙的 UIAbility,是獨立頁面的入口,主要負責:
FlutterAbilityAndEntryDelegate (包括 doInitialFlutterViewRun() 、生命週期映射和 FlutterEngineCache 、 FlutterEngineGroup 等邏輯)而這裡 FlutterEngine 就是 Flutter 在 Embedding 的 ArkTS 執行環境的實現,管理所有系統通道和插件,主要包括:
LifecycleChannel:應用生命週期NavigationChannel:路由導航TextInputChannel:文字輸入PlatformChannel:平台能力SettingsChannel:系統設置(亮度/字體/時鐘格式)LocalizationChannel:國際化/語言AccessibilityChannel:無障礙RestorationChannel:狀態恢復NativeVsyncChannel:原生垂直同步
FlutterNapi.init(),傳入bundlePath(應用包路徑)、appStoragePath(應用存儲路徑)、engineCachesPath(引擎緩存路徑)、args(命令行參數)、initTimeMillis(初始化時間戳)、productModel(設備型號)等參數FlutterNapi.xComponentAttachFlutterEngine() 將 XComponent 和 native Shell 綁定,核心是將 xcomponentId 與 nativeShellHolderId一般路徑: engine/src/flutter/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets
FlutterPage 是鴻蒙特有的渲染容器,用 XComponent 作為 Flutter 渲染的承載,FlutterPage.ets 中的 ArkUI XComponent 指定了 libraryname: 'flutter',所以會加載 libflutter.so 並觸發 library_loader.cpp 中的 NAPI 註冊:
然後每個 Flutter 實例對應一個 OHOSShellHolder,持有完整的 Flutter Shell:ohos_shell_holder,OHOS 通過自己的抽象層(OHOSContext/OHOSSurface)和 NAPI 橋接,不直接構造 FlutterRendererConfig,而是由 PlatformViewOHOS 的 CreateRenderingSurface() 返回對應的 Surface 和 CreateOHOSContext 返回渲染上下文

OH_NativeVSync 原生 VSync 信號驅動幀渲染,VsyncWaiterOHOS 負責等待信號並觸發幀調度,同時支援幀緩存模式的 Dvsync 開關:
EmbeddingNodeController(繼承 NodeController)實現,利用 BuilderNode 和 FrameNode 完成混合渲染,這個我們在之前的 《深入理解 Flutter 的 PlatformView 如何在鴻蒙平台實現混合開發》有聊過。最後簡單總結的話,類似如下結構:
| 類別 | 文件 | 角色 |
|---|---|---|
FlutterAbility |
embedding/ohos/FlutterAbility.ets |
UIAbility 子類;應用程序生命週期入口點 |
FlutterEntry |
embedding/ohos/FlutterEntry.ets |
OHOS 頁面級入口點;封裝了 FlutterPage |
FlutterView |
view/FlutterView.ets |
擁有 ViewportMetrics,路由觸摸/鍵盤/生命週期事件 |
FlutterNapi |
embedding/engine/FlutterNapi.ets |
調用 libflutter.so 導出;持有 nativeShellHolderId |
TextInputPlugin |
plugin/editing/TextInputPlugin.ets |
API 將 Flutter IME 協議橋接到 OHOS inputMethod API |
PlatformViewsController |
plugin/platform/PlatformViewsController.ets |
管理嵌入在 Flutter 中的 OHOS 原生視圖 |
| 類別 / 文件 | 角色 |
|---|---|
PlatformViewOHOSNapi |
將 C++ 函數導出為 NAPI 符號;處理 nativeInit、nativeAttach、nativeDispatchPlatformMessage、nativeSetViewportMetrics |
PlatformViewOHOS |
實現引擎的 PlatformView 接口;創建渲染上下文和表面。 |
OHOSXComponentAdapter |
接收`XComponent Surface 生命週期回調和觸摸事件 |
OHOSExternalTextureGL / OHOSExternalTextureVulkan |
GL 和 Vulkan 路徑的外部紋理支援 |
整體流程如果在鴻蒙視角下流程如下圖所示:

我們回顧一下,可以發現,Flutter 在適配鴻蒙的實現上接入十分乾淨,就是拓展了:
engine/src/flutter/shell/platform/ohos/:C++ 原生層實現,包含平台適配、渲染後端、NAPI 橋接等engine/src/flutter/shell/platform/ohos/flutter_embedding/:ArkTS 嵌入層實現,提供 Flutter 應用在鴻蒙上的運行時環境其中 flutter_embedding/ 主要提供 ArkTS 的環境嵌入支援:
FlutterAbility.ets、FlutterEntry.ets 提供兩種宿主模式FlutterEngine.ets、FlutterEngineGroup.ets 管理引擎實例與複用FlutterPlugin.ets 接口與插件註冊機制flutter_embedding/ 之外主要提供平台嵌入的底層 C++ 支持,通過 NAPI 與上層 ArkTS 交互
PlatformViewOHOS 實現 Flutter 的 PlatformView 接口OHOSSurface 系列類封裝 Vulkan/OpenGL/軟體渲染platform_view_ohos_napi.cpp 暴露 native 接口給 ArkTSohos_xcomponent_adapter.cpp 處理 XComponent 生命週期所以從整個鴻蒙的適配實現上,我們就可以很直觀看到 Flutter Embedder 的價值,它可以讓一個全新的系統和平台,用非常乾淨的方式接入 Flutter,並且平台只需要專注於 Embedder 層的實現即可,這也是為什麼 Flutter 在鴻蒙平台跟進速度最快的原因。
從這裡可以看出來,Flutter 的 Embedder 實現才是發揮 Flutter 最大價值的地方,只是它的門檻較高,一般情況只有企業才能發揮它的價值,這也是為什麼 Flutter 會出現在越來越多的產品裡的原因,甚至出現在小米核心應用層、OPPO 負一屏和微信小程序 skyline 的原因,因為它確實很好遷移到不同平台,甚至是特殊平台,你不用 Dart,也需要用它跨平台的渲染管道和 UI 編排能力。
當然,如果社區的 flutter_zero 項目能做起來的話,那 Flutter 的解耦和跨平台能力就可以進一步得到放大,不過這估計是很遙遠之後的事情了。
而現在,在有清晰的結構分層和已有的實現例子上,本身 AI 就可以很快的幫你實現一層 Embedder,這也是 Flutter 在 AI 時代更容易被小眾平台接入為渲染框架的原因。
所以,Flutter 更多的價值體現在於 Embedder 的設計,還有 Impeller 的發布,這些才是 Flutter 的核心資產。