Flutter Engine、Dart VM、Runner、鸿蒙端进程与线程 ------ 深度解析
本文基于 Flutter SDK
oh-3.35.7-dev分支源码,对 Flutter 在 OpenHarmony/HarmonyOS(以下简称 OHOS)端的架构进行深度解析。参考原文:Flutter Engine、Dart VM、Runner、iOS 进程与线程 ------ 深度解析,本文以相同的分析维度,深入剖析鸿蒙端的实现差异与核心机制。
一、整体架构总览
scss
┌──────────────────────────────────────────────────────────────┐
│ OHOS 进程 (Process) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ FlutterAbility (OHOS Host App) │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ FlutterEngine 实例 │ │ │
│ │ │ ┌────────────────────────────────────────────┐ │ │ │
│ │ │ │ Dart VM │ │ │ │
│ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ Dart Isolate (main) │ │ │ │ │
│ │ │ │ │ (你写的 Dart 业务代码) │ │ │ │ │
│ │ │ │ └──────────────────────────────────────┘ │ │ │ │
│ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ Dart Isolate (spawned) │ │ │ │ │
│ │ │ │ │ (compute / Isolate.spawn) │ │ │ │ │
│ │ │ │ └──────────────────────────────────────┘ │ │ │ │
│ │ │ └────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────┐ ┌───────────┐ ┌──────────────┐ │ │ │
│ │ │ │ UI Thread │ │ IO Thread │ │ Raster Thread│ │ │ │
│ │ │ │(Platform) │ │ │ │ (GPU) │ │ │ │
│ │ │ └───────────┘ └───────────┘ └──────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────── ──┐ │ │
│ │ │ OHOS 原生代码 (ArkTS: EntryAbility, Pages) │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ OHOS Main Thread ─── TaskPool/Worker ─── 其他系统线程 │
└──────────────────────────────────────────────────────────────┘
与 iOS 端架构对比
| 维度 | iOS | OHOS (鸿蒙) |
|---|---|---|
| 宿主应用 | Runner (Xcode Project) | FlutterAbility (OHOS Module) |
| 宿主基类 | UIViewController / FlutterAppDelegate | UIAbility / FlutterAbility |
| 原生语言 | Objective-C / Swift | ArkTS (eTS) |
| 原生桥接 | Objective-C Runtime | NAPI (N-API, C++ ↔ ArkTS) |
| 渲染表面 | CAMetalLayer / CAEAGLLayer | XComponent + OHNativeWindow |
| 图形后端 | Metal / OpenGL ES | OpenGL ES (Skia) / Vulkan (Impeller) |
| 包产物 | .ipa (Framework) | .hap / .har (HAR 模块) |
| 构建工具 | Xcode + xcodebuild | Hvigor + ohpm |
| VSync 机制 | CADisplayLink | OH_NativeVSync |
二、逐层深度解析
2.1 OHOS 进程 (Process)
OHOS 进程是最顶层的容器,是操作系统分配资源的基本单位。
- 一个 OHOS 应用运行在独立的应用沙盒进程中
- 进程内可包含多个 UIAbility 实例
- Flutter App 的所有组件(FlutterAbility、FlutterEngine、Dart VM)均运行在同一个进程中
- OHOS 使用 Stage 模型管理应用生命周期,进程由 AbilityManagerService 管理
scss
OHOS 进程
├── 进程内存空间
│ ├── FlutterAbility 的 ArkTS 代码
│ ├── Flutter Engine 的 C++ 代码 (libflutter.so)
│ ├── Dart VM 运行时
│ ├── Dart 堆内存 (Dart Heap)
│ └── 共享库 (libflutter.so, libace_ndk.z.so 等)
├── 文件描述符表
├── XComponent 原生窗口句柄
└── 线程表 (所有线程)
2.2 OHOS 线程 (Thread)
线程是 CPU 调度的基本单位,同一进程内的线程共享内存空间。
OHOS 中的关键线程类型
| 线程 | 说明 |
|---|---|
| Main Thread | 主线程,ArkUI 事件循环,UIAbility 生命周期回调 |
| TaskPool Worker | OHOS 提供的线程池(类似 GCD) |
| pthread | POSIX 线程,底层线程创建方式 |
Flutter 创建的线程
Flutter Engine 启动后会在 OHOS 进程内创建 4 个核心线程(Task Runner):
css
┌──────────────────────────────────────────────────────┐
│ Flutter 四大线程 │
├──────────────┬───────────────────────────────────────┤
│ Platform │ 复用 OHOS Main Thread │
│ Thread │ 处理 Platform Channel、插件调用、NAPI 交互│
├──────────────┼───────────────────────────────────────┤
│ UI Thread │ 独立 pthread │
│ (Dart Thread)│ 运行 Dart 代码、构建 Widget/Layer Tree │
├──────────────┼───────────────────────────────────────┤
│ Raster │ 独立 pthread │
│ Thread │ GPU 光栅化,将 Layer Tree 转为 GPU 指令 │
├──────────────┼───────────────────────────────────────┤
│ IO Thread │ 独立 pthread │
│ │ 图片解码、资源加载等耗时 IO 操作 │
└──────────────┴───────────────────────────────────────┘
OHOS 端的 QoS 线程优先级
与 iOS 使用 GCD 优先级不同,OHOS 使用 OH_QoS_SetThreadQoS 设置线程服务质量等级。源码位于 ohos_shell_holder.cpp 中的 OHOSPlatformThreadConfigSetter:
arduino
线程优先级与 QoS 映射 (OHOSPlatformThreadConfigSetter):
ThreadPriority::kDisplay → QOS_USER_INTERACTIVE (最高)
ThreadPriority::kRaster → QOS_USER_INTERACTIVE (最高)
ThreadPriority::kBackground → QOS_BACKGROUND (最低)
ThreadPriority::kNormal → QOS_DEFAULT (默认)
各线程实际配置:
├── Platform Thread → 复用 OHOS Main Thread,不经过此 setter
├── UI Thread → kDisplay → QOS_USER_INTERACTIVE
├── Raster Thread → kRaster → QOS_USER_INTERACTIVE
├── IO Thread → kNormal → QOS_DEFAULT
└── VSync 回调线程 → 首次回调时手动设置 QOS_USER_INTERACTIVE
注意:Platform Thread 直接复用 OHOS 主线程,其优先级由系统管理,不经过 OHOSPlatformThreadConfigSetter。VSync 回调 (OnVsyncFromOHOS) 在首次执行时会手动调用 OH_QoS_SetThreadQoS(QOS_USER_INTERACTIVE) 提升优先级。
合并 Platform/UI 线程模式
OHOS 端支持 Platform 与 UI 线程合并 的特殊模式:
ini
线程创建策略 (ohos_shell_holder.cpp):
默认模式:
mask = kRaster | kIo | kUi
→ 创建 3 个独立 pthread (UI, Raster, IO)
→ Platform Thread 复用 OHOS Main Thread
→ 共 4 个线程
合并模式 (merged_platform_ui_thread = kEnabled):
mask = kRaster | kIo
→ 仅创建 2 个独立 pthread (Raster, IO)
→ Platform Thread 与 UI Thread 共用 OHOS Main Thread
→ 共 3 个线程,减少线程切换开销
重要区分: Flutter 的 "UI Thread" 不是 OHOS 的 Main Thread。Flutter 的 Platform Thread 才是 OHOS 的 Main Thread。在合并模式下,两者运行在同一线程上。
2.3 FlutterAbility (OHOS 宿主应用)
FlutterAbility 是 OHOS 端的宿主,对应 iOS 端的 Runner。它本质上是一个标准的 OHOS UIAbility。
FlutterAbility 的项目结构
scss
ohos/ (OHOS 宿主工程)
├── AppScope/
│ └── app.json5 ← 应用级配置
├── entry/
│ └── src/main/
│ ├── ets/
│ │ ├── entryability/
│ │ │ └── EntryAbility.ets ← 继承 FlutterAbility
│ │ └── pages/
│ │ └── Index.ets ← 使用 FlutterEntry / FlutterPage
│ ├── resources/
│ └── module.json5 ← 模块配置
├── oh-package.json5 ← 依赖管理 (flutter.har)
└── build-profile.json5 ← 构建配置
FlutterAbility 的核心层级
scss
FlutterAbility (extends UIAbility)
├── FlutterAbilityAndEntryDelegate ← 代理模式,管理 Engine 和 View
│ ├── FlutterEngine ← ArkTS 端引擎实例
│ │ ├── DartExecutor ← Dart 代码执行器
│ │ ├── FlutterNapi ← NAPI 桥接 (ArkTS ↔ C++)
│ │ ├── FlutterRenderer ← 渲染器
│ │ ├── PlatformViewsController ← 平台视图控制器
│ │ └── System Channels ← 系统通道 (14 个)
│ ├── FlutterView ← 视图层
│ │ ├── XComponent ← 原生渲染组件
│ │ ├── EmbeddingNodeController ← 嵌入节点控制器
│ │ └── ViewportMetrics ← 视口度量
│ └── Plugin Registry ← 插件注册表
└── FlutterManager ← 全局 Ability/WindowStage 管理
FlutterAbility 的生命周期
scss
OHOS 系统启动进程
│
▼
UIAbility.onCreate(want, launchParam)
│
├── AppStorage.setOrCreate('fontSizeScale', ...) ← 冷启动获取系统字号
├── FlutterManager.getInstance().pushUIAbility() ← 注册到全局管理器
│
├── 创建 FlutterAbilityAndEntryDelegate
│ │
│ ├── delegate.onAttach(context)
│ │ ├── setupFlutterEngine()
│ │ │ ├── 优先级1: 复用缓存引擎 (cachedEngineId)
│ │ │ ├── 优先级2: 宿主自定义引擎 (provideFlutterEngine)
│ │ │ ├── 优先级3: 引擎组派生 (FlutterEngineGroup)
│ │ │ └── 优先级4: 新建引擎 (默认)
│ │ ├── 注册插件 (attachToAbility)
│ │ └── 获取系统语言 (getSystemLanguages)
│ │
│ └── delegate.onRestoreInstanceState(want)
│
├── 注册异常处理 (errorManager)
│ └── onUnhandledException → appRecovery.saveAppState() + restartApp()
│
└── Debug 模式: delegate.initWindow()
│
▼
UIAbility.onWindowStageCreate(windowStage)
│
├── FlutterManager.pushWindowStage() ← 注册窗口舞台
├── delegate.initWindow()
│
├── 创建 FlutterView
│ │
│ ├── FlutterManager.createFlutterView(context)
│ ├── 关联 FlutterEngine (attachToFlutterEngine)
│ └── 返回 FlutterView 实例
│
├── windowStage.loadContent(pagePath, storage)
│ └── 回调中: flutterView.onWindowCreated()
│
├── 全屏模式: FlutterManager.setUseFullScreen()
│
└── 注册窗口事件回调 (windowStageEvent)
│
├── FOREGROUND → delegate.onShow()
│ ├── flutterView.setActive(true)
│ └── lifecycleChannel.appIsResumed()
├── ACTIVE → delegate.onWindowStageChanged()
├── INACTIVE → delegate.onWindowStageChanged()
└── BACKGROUND → delegate.onHide()
├── flutterView.setActive(false)
└── lifecycleChannel.appIsPaused()
▼
UIAbility.onForeground() → delegate.onShow()
▼
UIAbility.onBackground() → delegate.onHide()
▼
UIAbility.onConfigurationUpdate(config)
│
├── 发送 SettingsChannel 消息
│ ├── alwaysUse24HourFormat (I18n.System.is24HourClock)
│ ├── platformBrightness (COLOR_MODE_DARK → DARK / LIGHT)
│ └── textScaleFactor (fontSizeScale)
├── 字体粗细: setFontWeightScale(fontWeightScale)
├── 语言变更: sendLocaleToFlutter()
└── 字体重载: onCheckAndReloadFont()
▼
UIAbility.onMemoryLevel(level)
│
├── MEMORY_LEVEL_CRITICAL → delegate.onLowMemory()
└── nativeSetQosOnLowMemory(level) → 降低线程 QoS 等级
▼
UIAbility.onWindowStageDestroy()
│
├── FlutterManager.popWindowStage()
└── delegate.onWindowStageDestroy()
▼
UIAbility.onDestroy()
│
├── FlutterManager.popUIAbility()
├── errorManager.off('error') ← 取消异常监听
├── flutterView.onDestroy()
└── delegate.onDetach() → release()
异常恢复机制 (OHOS 独有)
FlutterAbility 内置了 OHOS 的应用异常恢复机制:
scss
errorManager.on('error', observer)
│
└── onUnhandledException(errorMsg)
├── Log.e(TAG, errorMsg) ← 记录异常日志
├── appRecovery.saveAppState() ← 保存应用状态
└── appRecovery.restartApp() ← 重启应用
当 Dart 或原生层发生未处理异常时,OHOS 的 appRecovery 机制会自动保存状态并重启应用,避免直接崩溃退出,提升用户体验。
FlutterAbility vs FlutterEntry:两种宿主模式
OHOS 端提供两种 Flutter 集成方式,这是与 iOS 端的重要差异:
scss
┌───────────────────────────────────────────────────────────────---──┐
│ FlutterAbility (全屏模式) │ FlutterEntry (嵌入模式) │
├─────────────────────────────────────┼──────────────────────────---─┤
│ 继承 UIAbility │ 实现 Host 接口 │
│ 独立 Ability,生命周期自管理 │ 嵌入到现有 Page 中 │
│ onCreate → onWindowStageCreate │ aboutToAppear (Page 生命周期) │
│ onDestroy │ aboutToDisappear │
│ 自动管理 WindowStage │ 依赖外部 WindowStage │
│ windowStage.loadContent(pagePath) │ Page 自行加载内容 │
│ 适用于: 纯 Flutter 应用 │ 适用于: Flutter 嵌入原生页面 │
│ 类比 iOS: FlutterAppDelegate │ 类比 iOS: FlutterViewController │
└─────────────────────────────────────┴────────────────────────---───┘
| 对比项 | FlutterAbility | FlutterEntry |
|---|---|---|
| 宿主类型 | UIAbility (应用级) | ArkUI 组件 (页面级) |
| 生命周期 | onCreate / onDestroy |
aboutToAppear / aboutToDisappear |
| 视图创建 | onWindowStageCreate 中创建 |
aboutToAppear 中创建 |
| WindowStage | 自动获取 | 从 FlutterManager 获取 |
| 内容加载 | windowStage.loadContent() |
直接在 Page 中渲染 |
| 前后台 | onForeground / onBackground |
onPageShow / onPageHide |
| 环境变更 | onConfigurationUpdate |
registerEnvironmentCallback |
| 使用场景 | 纯 Flutter 应用或独立 Ability | Add-to-App、混合页面 |
与 iOS Runner 的关键差异
| 对比项 | iOS Runner | OHOS FlutterAbility |
|---|---|---|
| 基类 | FlutterAppDelegate (UIApplicationDelegate) | FlutterAbility (UIAbility) |
| 视图控制器 | FlutterViewController | FlutterView + FlutterPage |
| 页面嵌入 | FlutterViewController (push/present) | FlutterEntry (组件嵌入) |
| 窗口管理 | UIWindow | WindowStage |
| 生命周期粒度 | App + ViewController | UIAbility + WindowStage + Page |
| 异常恢复 | 无内置机制 | errorManager + appRecovery |
| 配置变更 | NotificationCenter 通知 | onConfigurationUpdate 回调 |
| 包产物 | Flutter.framework + App.framework | flutter.har + libflutter.so |
核心理解: FlutterAbility 是"壳",FlutterEngine 是"核心"。FlutterAbility 负责 OHOS 层面的事务(权限、生命周期、窗口管理等),FlutterEngine 负责 Flutter 的一切。
FlutterEntry则是为混合开发场景设计的页面级容器。
2.4 Flutter Engine (鸿蒙端)
Flutter Engine 是用 C/C++ 编写的核心运行时。在 OHOS 端,Engine 通过 NAPI 与 ArkTS 层通信,通过 XComponent 获取原生渲染表面。
Engine 的组成
scss
FlutterEngine (OHOS)
├── Dart Runtime (Dart VM)
│ ├── Dart Isolate 管理
│ ├── GC (垃圾回收器)
│ └── JIT / AOT 编译器
│
├── Shell (壳层)
│ ├── Platform Shell (OHOS 适配层)
│ │ ├── OhosMain ← NAPI 入口,初始化引擎
│ │ ├── OHOSShellHolder ← Shell 持有者
│ │ ├── PlatformViewOHOS ← 平台视图层
│ │ ├── PlatformViewOHOSNapi ← NAPI 桥接 (80+ 个方法)
│ │ ├── VsyncWaiterOHOS ← VSync 等待器
│ │ ├── OhosTouchProcessor ← 触摸事件处理
│ │ └── XComponentAdapter ← XComponent 适配器
│ │
│ └── Task Runner 管理
│ ├── PlatformTaskRunner → OHOS Main Thread
│ ├── UITaskRunner → Dart 执行线程
│ ├── RasterTaskRunner → GPU 光栅化线程
│ └── IOTaskRunner → IO 线程
│
├── Skia / Impeller (图形引擎)
│ ├── OpenGL ES + Skia (ohos_surface_gl_skia)
│ ├── Vulkan + Impeller (ohos_surface_vulkan_impeller)
│ ├── Software 渲染 (ohos_surface_software)
│ ├── 文字排版 (libtxt / platform_ohos.cc)
│ └── 图片解码 (OHOSImageGenerator)
│
├── 无障碍 (Accessibility)
│ ├── OhosSemanticsBridge
│ ├── OhosSemanticsNode
│ └── OhosSemanticsTree
│
└── Platform Channel 机制
├── MethodChannel
├── BasicMessageChannel
└── EventChannel
Engine 在 OHOS 中的存在形式
css
flutter.har (Flutter 引擎 HAR 包)
├── libs/
│ ├── arm64-v8a/
│ │ └── libflutter.so ← C++ 引擎动态库
│ └── armeabi-v7a/
│ └── libflutter.so
├── src/main/ets/
│ ├── embedding/
│ │ ├── engine/ ← 引擎 ArkTS 层
│ │ │ │ ├── FlutterEngine.ets
│ │ │ ├── FlutterNapi.ets ← NAPI 绑定
│ │ │ ├── DartExecutor.ets
│ │ │ ├── systemchannels/ ← 14 个系统通道
│ │ │ └── plugins/ ← 内置插件
│ │ └── ohos/ ← OHOS 集成层
│ │ ├── FlutterAbility.ets
│ │ ├── FlutterEntry.ets
│ │ └── FlutterAbilityAndEntryDelegate.ets
│ └── view/
│ └── FlutterView.ets ← 视图组件
└── resources/
└── rawfile/
└── flutter_assets/ ← Dart 编译产物和资源
Dart AOT 编译产物:
├── vm_snapshot_data
├── isolate_snapshot_data
├── kernel_blob.bin (Debug 模式)
└── AssetManifest.json
NAPI 桥接机制 (PlatformViewOHOSNapi)
NAPI 是 OHOS 端 C++ 与 ArkTS 通信的核心桥梁,对应 iOS 端的 Objective-C Runtime 方法调用。PlatformViewOHOSNapi 提供了 80+ 个 NAPI 方法:
scss
PlatformViewOHOSNapi (C++ ↔ ArkTS 桥接)
├── 引擎生命周期
│ ├── nativeAttach() ← 创建 ShellHolder
│ ├── nativeSpawn() ← 派生新引擎(共享 Dart VM)
│ └── nativeDestroy() ← 销毁引擎
│
├── Platform Channel 消息
│ ├── nativeDispatchPlatformMessage()
│ ├── nativeDispatchEmptyPlatformMessage()
│ ├── nativeInvokePlatformMessageResponseCallback()
│ └── FlutterViewHandlePlatformMessage() ← C++ → ArkTS
│
├── 渲染表面 (XComponent)
│ ├── SurfaceCreated()
│ ├── SurfaceChanged()
│ ├── SurfaceDestroyed()
│ ├── nativeXComponentAttachFlutterEngine()
│ ├── nativeXComponentDetachFlutterEngine()
│ └── nativeXComponentPreDraw()
│
├── 显示信息
│ ├── nativeSetViewportMetrics()
│ ├── nativeUpdateRefreshRate()
│ ├── nativeUpdateSize()
│ └── nativeUpdateDensity()
│
├── Dart 执行
│ ├── nativeRunBundleAndSnapshotFromLibrary()
│ ├── nativeLoadDartDeferredLibrary()
│ └── nativeDeferredComponentInstallFailure()
│
├── 纹理管理
│ ├── nativeRegisterTexture()
│ ├── nativeUnregisterTexture()
│ ├── nativeMarkTextureFrameAvailable()
│ └── nativeRegisterPixelMap()
│
├── 无障碍
│ ├── nativeSetSemanticsEnabled()
│ ├── nativeAccessibilityStateChange()
│ └── nativeAccessibilityAnnounce()
│
└── 性能优化
├── nativeSetDVsyncSwitch() ← 动态 VSync
├── nativeAnimationVoting() ← 帧率投票
├── nativeVideoVoting() ← 视频帧率投票
└── nativeSetQosOnLowMemory() ← 低内存 QoS 调整
2.5 Dart VM (鸿蒙端)
Dart VM 在鸿蒙端的运行方式与 iOS 端基本一致,是 FlutterEngine 内部的虚拟机运行时。
两种运行模式
scss
┌─────────────────────────────────────────┐
│ Debug 模式 (JIT) │
│ │
│ Dart 源码 → Kernel Binary → JIT 编译 │
│ → 解释执行 + 热编译为机器码 │
│ │
│ 特点:支持 Hot Reload / Hot Restart │
│ 有 Dart VM 完整编译器 │
│ 性能较低 │
│ 通过 hdc 连接设备 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ Release 模式 (AOT) │
│ │
│ Dart 源码 → AST → IR → ARM64 机器码 │
│ → 直接 CPU 执行 │
│ │
│ 特点:不支持 Hot Reload │
│ 无 JIT 编译器 (体积更小) │
│ 性能接近原生 │
│ 通过 gen_snapshot 生成快照 │
└─────────────────────────────────────────┘
Dart VM 的内存结构(与 iOS 一致)
scss
Dart VM 内存布局
├── New Space (新生代)
│ ├── Semi-Space A (活跃区)
│ └── Semi-Space B (备用区)
│ └── Scavenger GC (复制算法, STW 很短)
│
├── Old Space (老生代)
│ ├── 大对象区
│ └── 普通对象区
│ └── Mark-Sweep / Mark-Compact GC
│
├── Code Space (代码区)
│ └── AOT 编译后的机器码
│
├── Image Space (镜像区)
│ ├── vm_snapshot_data
│ └── isolate_snapshot_data
│
└── Isolate 独有内存
├── 每个 Isolate 有独立的堆
└── Isolate 间不共享内存 (通过 SendPort/ReceivePort 通信)
Dart Isolate 与 OHOS 线程的关系
scss
┌─────────────────────────────────────────────────┐
│ │
│ Dart Isolate ≠ OHOS Thread │
│ 但 Dart Isolate 运行在 OHOS Thread 之上 │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Root Isolate │ ──→ │ UI Thread │ │
│ │ (main) │ │ (固定绑定) │ │
│ └─────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Spawned │ ──→ │ Dart VM 线程池中 │ │
│ │ Isolate │ │ 的某个 pthread │ │
│ └─────────────┘ └─────────────────┘ │
│ │
│ 一个 Isolate 在同一时刻只在一个线程上运行 │
│ 但 Dart VM 可以将 Isolate 调度到不同线程上 │
│ │
└─────────────────────────────────────────────────┘
OHOS 端平台检测
在 Dart 层,OHOS 平台通过以下方式识别:
dart
// packages/flutter/lib/src/foundation/_platform_io.dart
if (Platform.operatingSystem == 'ohos')
defaultTargetPlatform = TargetPlatform.ohos;
TargetPlatform 枚举包含 ohos 值,在 Widget 层大量用于平台差异化行为(如 scroll_position.dart、navigator.dart、editable_text.dart、material/scaffold.dart 等)。
运行时 vs 构建时目标:
| 类型 | 枚举值 | 用途 |
|---|---|---|
| 运行时 | TargetPlatform.ohos |
defaultTargetPlatform,Widget 平台差异化 |
| 构建目标 | TargetPlatform.ohos_arm |
32 位 ARM (armeabi-v7a) |
| 构建目标 | TargetPlatform.ohos_arm64 |
64 位 ARM (arm64-v8a) |
| 构建目标 | TargetPlatform.ohos_x64 |
x86_64 模拟器 |
构建时使用 ohos_arm / ohos_arm64 / ohos_x64 区分 ABI,对应 ohos-arm、ohos-arm64、ohos-x64 产物路径;运行时 Platform.operatingSystem == 'ohos' 统一返回 TargetPlatform.ohos。
三、渲染管线深度解析
3.1 渲染后端选择
OHOS 端支持三种渲染后端,在 OhosMain::Init() 中根据配置参数选择。以下是源码中的选择逻辑:
php
渲染后端选择逻辑 (ohos_main.cpp):
if (enable_software_rendering) {
// 软件渲染,不能与 Impeller 同时启用
→ OHOSRenderingAPI::kSoftware
} else if (enable_impeller) {
// 启用 Impeller,使用 Vulkan
→ OHOSRenderingAPI::kImpellerVulkan
} else {
// 默认使用 OpenGL ES
→ OHOSRenderingAPI::kOpenGLES
}
// 二次校验确保一致性:
kSoftware / kOpenGLES → enable_impeller = false
kImpellerVulkan → enable_impeller = true
scss
┌───────────────────────────────────────────────────────────┐
│ OHOS 渲染后端详情 │
├──────────────────┬────────────────────────────────────────┤
│ Software │ 纯 CPU 渲染,无 GPU 加速 │
│ (kSoftware) │ 不支持 Impeller │
│ │ 用于特殊场景/回退 │
├──────────────────┼────────────────────────────────────────┤
│ OpenGL ES + │ EGL + OpenGL ES 3.0 + Skia │
│ Skia (默认) │ 使用 EGL 创建 onscreen/offscreen 表面 │
│ (kOpenGLES) │ 通过 GrDirectContext 管理 GPU 上下文 │
│ │ 模拟器 Mali-G78 兼容: 刷新 GL 版本字符串 │
├──────────────────┼────────────────────────────────────────┤
│ Vulkan + │ Vulkan 1.0+ + Impeller │
│ Impeller │ 使用 SurfaceContextVK 管理 Vulkan 表面 │
│ (kImpellerVulkan)│ 支持动态 VSync、帧率投票、预加载 GPU 表面│
│ │ 使用 Swapchain 管理帧缓冲 │
└──────────────────┴────────────────────────────────────────┘
3.2 XComponent 渲染表面
OHOS 端使用 XComponent 组件作为渲染表面载体,这是与 iOS 端最核心的差异之一。
需要注意的是,XComponent 实际上在 FlutterPage.ets 中创建,而非 FlutterView.ets:
scss
┌─────────────────────────────────────────────────────────────┐
│ XComponent 渲染流程 │
│ │
│ ArkTS 层 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ FlutterPage.ets (UI 组件层) │ │
│ │ └── XComponent({ id: viewId, type: SURFACE, │ │
│ │ libraryname: 'flutter' }) │ │
│ │ ├── onLoad → flutterView.onSurfaceCreated()│ │
│ │ └── onDestroy → flutterView.onSurfaceDestroyed()│ │
│ │ │ │ │
│ │ ├── enableFrameCacheForSmooth (默认 true) │ │
│ │ │ → 高刷屏启用帧缓存,牺牲一帧延迟换平滑度 │ │
│ │ └── API < 15: setOnVisibleAreaApproximateChange│ │
│ │ → 部分可见时 nativeUpdateCurrentXComponentId│ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ FlutterView.ets (逻辑层) │ │
│ │ ├── 管理 ViewportMetrics、避让区域、键盘 │ │
│ │ ├── attachToFlutterEngine(engine) │ │
│ │ │ └── nativeXComponentAttachFlutterEngine(id) │ │
│ │ └── onSurfaceDestroyed() │ │
│ │ └── nativeXComponentDetachFlutterEngine(id) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ NAPI 调用 │
│ ▼ │
│ C++ 层 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ XComponentAdapter (单例) │ │
│ │ └── XComponentBase │ │
│ │ ├── OH_NativeXComponent_RegisterCallback() │ │
│ │ ├── OH_NativeXComponent_GetTouchEvent() │ │
│ │ └── OH_NativeXComponent_GetMouseEvent() │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ 获取 OHNativeWindow │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ OHOSSurface (渲染表面抽象) │ │
│ │ ├── OhosSurfaceGLSkia → EGL + Skia 渲染 │ │
│ │ ├── OHOSSurfaceVulkanImpeller → Vulkan + Impeller │ │
│ │ └── OhosSurfaceSoftware → 软件渲染 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ GPU 提交 │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ OHOS 合成器 (RenderService) │ │
│ │ └── 合成 Flutter 层与原生 ArkUI 层 → 屏幕显示 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
与 iOS 渲染表面对比
| 对比项 | iOS | OHOS |
|---|---|---|
| 渲染载体 | CAMetalLayer / CAEAGLLayer | XComponent + OHNativeWindow |
| 表面创建 | layerClass 重写 | XComponent onSurfaceCreated 回调 |
| 窗口句柄 | UIWindow | OHNativeWindow (OH_NativeWindow_*) |
| 合成器 | Core Animation | RenderService |
| GPU API | Metal (主) / OpenGL ES | Vulkan / OpenGL ES |
3.3 一帧的渲染流程
less
时间线 ──────────────────────────────────────────────────────────→
OH_NativeVSync 信号到达 (16.67ms 一次 @60fps)
│
│ ① Platform Thread (OHOS Main Thread)
│ ┌──────────────────────────────────────┐
│ │ OH_NativeVSync_RequestFrameWithMulti │
│ │ Callback 接收 VSync 回调 │
│ │ 通知 UI Thread 开始新一帧 │
│ │ │
│ │ [可选] VSync 投票(OhosVsyncVotingMgr)│
│ │ 根据动画/视频状态投票帧率 │
│ └───────────────────┬──────────────────┘
│ │
│ ② UI Thread (Dart Thread)
│ ┌───────────────────▼──────────────────┐
│ │ 执行 Dart 代码 │
│ │ ├── Build Phase (Widget Tree) │
│ │ ├── Layout Phase (大小/位置计算) │
│ │ ├── Paint Phase (绘制指令生成) │
│ │ └── 生成 Layer Tree │
│ └───────────────────┬──────────────────┘
│ │
│ ③ Raster Thread (GPU Thread)
│ ┌───────────────────▼──────────────────┐
│ │ 接收 Layer Tree │
│ │ ├── Skia/Impeller 光栅化 │
│ │ ├── 生成 GPU 指令 │
│ │ └── 提交到 OpenGL ES / Vulkan │
│ └───────────────────┬──────────────────┘
│ │
│ ④ OHOS RenderService (合成器)
│ ┌───────────────────▼──────────────────┐
│ │ 合成 Flutter 层与 ArkUI 原生层 │
│ │ 提交到屏幕显示 │
│ └──────────────────────────────────────┘
3.4 VSync 机制(鸿蒙端特色)
OHOS 使用 OH_NativeVSync API 替代 iOS 的 CADisplayLink,并额外支持动态 VSync 和帧率投票:
scss
VsyncWaiterOHOS
├── 初始化
│ └── OH_NativeVSync_Create("flutterSyncName")
│
├── 等待 VSync (AwaitVSync)
│ │
│ ├── 1. 先执行帧率投票 VSyncVotingFrameRate()
│ │ └── 调度到 IO Task Runner
│ │ └── OhosVsyncVotingMgr::VotingByNativeVsync(handle)
│ │
│ └── 2. 调度到 UI Task Runner
│ └── OH_NativeVSync_RequestFrameWithMultiCallback(handle, callback)
│
├── VSync 回调 (OnVsyncFromOHOS)
│ ├── 首次调用: OH_QoS_SetThreadQoS(QOS_USER_INTERACTIVE)
│ │
│ ├── 获取 VSync 周期: GetVsyncPeriod()
│ │
│ ├── [帧缓存] 高于 60Hz 时启用
│ │ │ 条件: enable_frame_cache_ == true && vsync_period < 15ms
│ │ │ (15ms ≈ 66.7fps,即 > 60Hz 的高刷屏)
│ │ │
│ │ └── vsync_period += (vsync_period - 1ms)
│ │ → 牺牲一帧延迟换取平滑度
│ │ → 例: 120Hz 时 8.33ms → 8.33 + 7.33 = 15.66ms
│ │
│ ├── 计算 target_time = frame_time + vsync_period
│ │
│ └── ConsumePendingCallback → FireCallback(frame_start, frame_target)
│
├── 帧率投票 (OHOS 独有,LTPO 屏幕支持)
│ ├── OhosVsyncVotingMgr (单例)
│ │ ├── 投票优先级:
│ │ │ ├── 触摸按下 → 120 FPS (最高帧率)
│ │ │ ├── 触摸抬起 3s 内 → 60 FPS (过渡)
│ │ │ ├── 触摸抬起 100ms 内 → 120 FPS (快速操作)
│ │ │ ├── PlatformView 存在 → 120 FPS
│ │ │ └── 动画速度投票 → 可配置帧率
│ │ │
│ │ ├── 支持帧率: 120, 90, 72, 60, 30 FPS, 0 (不投票)
│ │ │
│ │ ├── OH_NativeVSync_SetExpectedFrameRateRange
│ │ │ └── {min: 30, max: 120, expected: <voted_fps>}
│ │ │
│ │ └── 降频稳定策略 (DelayFrameRateDropForStability):
│ │ └── 从高帧率切换到低帧率时,保持高帧率 4 个 VSync 周期
│ │ 再切换,避免突然降频导致的视觉卡顿
│ │
│ ├── nativeAnimationVoting() ← Dart 动画投票
│ └── nativeVideoVoting() ← 视频播放投票
│
└── 动态 VSync (API 14+)
├── 动态加载 libnative_vsync.so
└── OH_NativeVSync_DVSyncSwitch(handle, enable)
└── 由 Dart 侧通过 nativeSetDVsyncSwitch 控制
这是 OHOS 端相较于 iOS 端的重要优化点。通过 LTPO (Low Temperature Polycrystalline Oxide) 屏幕的帧率投票机制,Flutter 可以根据当前场景动态调整刷新率:静态界面 30Hz 省电、滚动/动画 120Hz 流畅,实现功耗与体验的最佳平衡。
四、Platform Channel 调用流程
4.1 消息传递架构
scss
Dart 代码 (UI Thread) ArkTS 代码 (Platform Thread)
│ │
│ MethodChannel.invokeMethod('getBattery') │
│ ──────────────────────────────────────→ │
│ [序列化为二进制消息] │
│ [从 UI Thread 调度到 Platform Thread] │
│ │
│ ┌─── NAPI 桥接 ───┐ │
│ │ │ │
│ │ C++ 引擎层 │ │
│ │ PlatformMessage │ │
│ │ HandlerOHOS │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ FlutterView │ │
│ │ HandlePlatform │ │
│ │ Message() │ │
│ └─────┬────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ OHOS Platform Thread │ │
│ │ 执行 ArkTS 原生代码 │ │
│ │ (调用 OHOS 系统 API) │ │
│ └──────────┬───────────┘ │
│ │ │
│ ←──────────────────────────────────────── │
│ [结果通过 NAPI 回传] │
│ [从 Platform Thread 调度回 UI Thread] │
│ │
▼ ▼
收到 Future 结果 调用完成
4.2 系统通道一览
FlutterEngine (ArkTS 层) 的 init() 方法中创建 14 个系统通道(源码顺序):
| 序号 | 系统通道 | Channel Name | 功能 |
|---|---|---|---|
| 1 | LifecycleChannel | flutter/lifecycle |
应用生命周期状态同步 (resumed/inactive/paused/detached) |
| 2 | NavigationChannel | flutter/navigation |
路由导航、初始路由、返回键拦截 |
| 3 | TextInputChannel | flutter/textinput |
文本输入、输入法交互 |
| 4 | TestChannel | - | 测试专用通道 |
| 5 | PlatformChannel | flutter/platform |
剪贴板、振动、屏幕方向、系统 UI、系统导航 |
| 6 | SensitiveContentChannel | - | 敏感内容保护 (OHOS 特有) |
| 7 | SystemChannel | flutter/system |
系统级消息 (内存警告等) |
| 8 | MouseCursorChannel | flutter/mousecursor |
鼠标光标形状控制 |
| 9 | DisplayMetricsChannel | - | 显示度量信息 (分辨率、DPI) |
| 10 | RestorationChannel | flutter/restoration |
页面状态保存与恢复 |
| 11 | SettingsChannel | flutter/settings |
系统设置 (深色模式、字体缩放、24小时制) |
| 12 | LocalizationChannel | flutter/localization |
国际化/本地化 (语言、地区) |
| 13 | AccessibilityChannel | flutter/accessibility |
无障碍服务状态和功能 |
| 14 | NativeVsyncChannel | - | 原生 VSync 回调 (OHOS 特有) |
其中 SensitiveContentChannel 和 NativeVsyncChannel 是 OHOS 端特有的通道,在其他平台不存在。
五、生命周期映射
5.1 OHOS UIAbility 生命周期 → Flutter 生命周期
scss
┌────────────────────────────────────────────────────────────┐
│ UIAbility 状态 │ 窗口焦点 │ Flutter 生命周期 │
├───────────────────────────┼───────────┼───────────────────┤
│ onCreate │ focused │ resumed │
│ onCreate │ unfocused│ inactive │
│ onForeground │ focused │ resumed │
│ onForeground │ unfocused│ inactive │
│ onBackground │ 任意 │ paused │
│ onDestroy │ 任意 │ detached │
└────────────────────────────────────────────────────────────┘
5.2 完整生命周期流转
markdown
┌──────────┐
│ detached │ ← 初始状态 / onDestroy
└────┬─────┘
│ onCreate
▼
┌──────────┐
┌────→│ inactive │←────┐
│ └────┬─────┘ │
失去焦点 │ │ 获得焦点 │ onBackground
│ ▼ │
│ ┌──────────┐ │
└─────│ resumed │─────┘
└────┬─────┘
│ onBackground
▼
┌──────────┐
│ paused │
└────┬─────┘
│ onDestroy
▼
┌──────────┐
│ detached │
└──────────┘
5.3 与 iOS 生命周期的对比
| Flutter 状态 | iOS 触发 | OHOS 触发 |
|---|---|---|
| resumed | applicationDidBecomeActive | onForeground + window focused |
| inactive | applicationWillResignActive | onForeground + window unfocused |
| paused | applicationDidEnterBackground | onBackground |
| detached | 进程终止 | onDestroy |
六、触摸与输入事件处理
6.1 触摸事件流程
scss
用户触摸屏幕
│
▼
OHOS 系统分发事件
│
▼
XComponent 接收触摸事件
│
├── OH_NativeXComponent_GetTouchEvent()
│
▼
OhosTouchProcessor::HandleTouchEvent()
│
├── 过滤重复 Down/Up 事件 (shouldDropTouchEvent)
├── 维护活跃手指 ID 集合 (activeFingerIds_)
├── 映射工具类型 → PointerData::DeviceKind
│ ├── FINGER → kTouch
│ ├── PEN → kStylus
│ └── MOUSE → kMouse
├── 构建 PointerData
├── DispatchPointerDataPacket() → 发送到 Dart 引擎
├── PlatformViewOnTouchEvent() → 转发到 ETS 层平台视图
└── VsyncVotingTouchValue() → VSync 帧率投票
6.2 鸿蒙端特有输入支持
scss
OhosTouchProcessor
├── HandleTouchEvent() ← 触摸
├── HandleMouseEvent() ← 鼠标 (hover, click, leave)
├── HandleAxisEvent() (API 15+)
│ ├── HandleScaleEvent() ← Ctrl + 滚轮 = 缩放
│ ├── HandleScrollEvent() ← 滚轮 = 滚动
│ └── HandlePanZoomEvent() ← 触控板 = 平移/缩放
└── HandleVirtualTouchEvent() ← 旧 API 鼠标转触摸兼容
七、多 Engine 场景 (Add-to-App)
css
OHOS 进程
├── FlutterAbility
│ ├── FlutterEngine A (主引擎)
│ │ ├── Dart VM (进程内唯一,共享) ◄──── 重要!
│ │ ├── Root Isolate A
│ │ ├── 4 个线程 (Platform/UI/Raster/IO)
│ │ └── FlutterView A (XComponent A)
│ │
│ ├── FlutterEngine B (第二个引擎, 通过 nativeSpawn)
│ │ ├── Dart VM (复用同一个) ◄──── 同一个 Dart VM
│ │ ├── Root Isolate B (独立的 Isolate)
│ │ ├── 共享 ThreadHost (Raster/IO),独立 UI Thread
│ │ └── FlutterView B (XComponent B)
│ │
│ └── FlutterEngineGroup (管理多引擎)
│ └── 共享 Dart VM + 资源,减少额外内存开销
│
├── FlutterEntry A (页面 A)
│ └── 使用 Engine A 通过 cachedEngineId
│
└── FlutterEntry B (页面 B)
└── 使用 Engine B 通过 cachedEngineId
核心要点: 一个 OHOS 进程中只有一个 Dart VM 实例,但可以有多个 FlutterEngine,每个 Engine 有自己独立的 Root Isolate。多引擎通过
nativeSpawn创建,共享 ThreadHost 和 AssetProvider。
7.2 FlutterEngineGroup 机制
FlutterEngineGroup.ets 是管理多引擎的核心类,实现了高效的引擎派生:
scss
FlutterEngineGroup
├── createAndRunEngineByOptions(options: Options)
│ │
│ ├── 首个引擎 (activeEngines 为空):
│ │ ├── createEngine(options) → 完整创建
│ │ ├── init(context, dartVmArgs)
│ │ └── runBundleAndSnapshotFromLibrary(entrypoint, libraryUrl)
│ │
│ └── 后续引擎 (activeEngines 不为空):
│ └── activeEngines[0].spawn(entrypoint, libraryUrl, initialRoute, args)
│ │
│ │ C++ 层 (nativeSpawn):
│ ├── 共享 Dart VM (进程唯一)
│ ├── 共享 ThreadHost (Raster + IO 线程)
│ ├── 共享 AssetProvider (资源提供者)
│ ├── 独立 Root Isolate
│ └── 可独立 UI Thread (如果未合并)
│
├── activeEngines: FlutterEngine[] ← 追踪所有活跃引擎
│
└── EngineLifecycleListenerImpl
└── onEngineWillDestroy() → 从 activeEngines 移除
引擎复用策略 (FlutterAbilityAndEntryDelegate.setupFlutterEngine):
css
优先级 1: 缓存引擎 (getCachedEngineId)
└── FlutterEngineCache.getInstance().get(id)
优先级 2: 宿主自定义引擎 (provideFlutterEngine)
└── host.provideFlutterEngine(context)
优先级 3: 引擎组派生 (getCachedEngineGroupId)
└── FlutterEngineGroupCache.get(id).createAndRunEngineByOptions()
优先级 4: 新建引擎 (默认)
└── new FlutterEngineGroup().createAndRunEngineByOptions()
八、外部纹理与 GPU 资源管理
8.1 外部纹理机制 (External Texture)
OHOS 端的外部纹理实现(如视频播放、相机预览等)使用 OH_NativeImage 和 OHNativeWindow。支持 GL 和 Vulkan 两种后端:
css
外部纹理工作流:
Dart 层
│ nativeRegisterTexture(textureId)
▼
C++ 层 (PlatformViewOHOS)
│ CreateExternalTexture()
│ ├── OpenGL ES 模式 → OHOSExternalTextureGL
│ └── Vulkan/Impeller 模式 → OHOSExternalTextureVulkan
▼
OHOSExternalTexture (基类)
├── OH_NativeImage_Create(0, GL_TEXTURE_EXTERNAL_OES)
├── OH_NativeImage_AcquireNativeWindow()
├── OH_NativeImage_SetOnFrameAvailableListener()
│
│ 纹理帧更新流程:
│ ├── 生产者 (相机/视频解码器) 写入 NativeWindow Buffer
│ ├── nativeMarkTextureFrameAvailable()
│ └── CreateDlImage() / CreateDlImage (Vulkan)
│
OHOSExternalTextureGL:
│ ├── eglCreateImageKHR(EGL_NATIVE_BUFFER_OHOS)
│ ├── glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES)
│ └── GPU 同步: eglCreateSyncKHR + eglDupNativeFenceFD
│
OHOSExternalTextureVulkan:
│ ├── CreateVkSemaphore() 创建 Vulkan 信号量
│ └── WaitGPUFence() 等待 fence
│
└── ImageLRU: Buffer 缓存复用和淘汰策略
OHOS 还支持直接注册 PixelMap 作为纹理,以及为纹理设置背景色/背景图:
css
PixelMap 纹理:
├── nativeRegisterPixelMap(textureId, pixelMap)
├── nativeSetTextureBackGroundPixelMap(textureId, pixelMap)
├── nativeSetTextureBackGroundColor(textureId, color)
├── nativeGetTextureWindowId(textureId) → 窗口 ID
└── nativeSetExternalNativeImage(textureId, image) → 直接绑定 NativeImage
8.2 GPU 资源回收机制 (OHOS 独有)
当应用进入后台时,OHOS 端实现了 GPU 资源的主动回收与恢复,这是 iOS 端没有的优化。回收决策由 GpuReclaimDecision 根据 onMemoryLevel 等回调决定:
ini
GPU 资源回收流程 (PlatformViewOHOS):
应用进入后台 / 低内存 (NotifyLifecycleChanged / onMemoryLevel)
│
▼
GpuReclaimDecision 决策
├── kAggressive → ExecuteReclaimAggressive()
└── kRestore → ExecuteReclaimRestore()
ExecuteReclaimAggressive() [进入后台时]
├── 开启帧门 (frame_gate_enabled_ = true)
│ └── 阻止外部纹理继续提交新帧
├── 标记 onscreen_context_valid_ = false
├── 缓存 NativeWindow 到 cached_native_window_
├── Raster 线程同步执行:
│ ├── GL/Skia: TryFreeSkiaGpuResources() 释放 GPU 资源
│ ├── TeardownOnScreenContext()
│ │ ├── GL/Skia: 释放 EGL onscreen surface 和 context
│ │ └── Vulkan/Impeller: 释放 swapchain
│ └── 释放 DMA 缓冲区
└── RunOnRasterAndWait 确保同步完成
应用回到前台 (onForeground)
│
▼
ExecuteReclaimRestore()
├── 关闭帧门 (frame_gate_enabled_ = false)
│ └── 允许外部纹理恢复更新
├── ShouldRebuildOnscreenContext() 检查是否需要重建
├── PostRebuildOnscreenContextTasks()
│ ├── Raster 线程: SetDisplayWindow(cached_native_window_)
│ ├── 重建 EGL surface / Vulkan swapchain
│ └── Platform 线程: onscreen_context_valid_ = true, ScheduleFrame()
└── 触发重新渲染
九、构建与打包
9.1 构建流程
scss
flutter build hap (OHOS 构建命令)
│
▼
OhosBuilder (flutter_tools)
│
├── ① Dart 编译
│ ├── Debug: kernel_blob.bin (JIT)
│ └── Release: gen_snapshot → AOT 快照 (ARM64 机器码)
│
├── ② 资源处理
│ ├── flutter_assets/ → rawfile/
│ ├── buildinfo.json (构建信息)
│ └── frames_cfg.json (帧配置)
│
├── ③ 引擎准备
│ ├── 复制 flutter.har (引擎 HAR 包)
│ └── 复制 libflutter.so (对应 ABI)
│
├── ④ 插件处理
│ ├── OhosPluginsManager 收集插件依赖
│ ├── ohpm install (安装依赖)
│ ├── assembleHars() (构建插件 HAR)
│ └── assembleHsps() (构建插件 HSP)
│
└── ⑤ Hvigor 构建
├── assembleHap → .hap 文件
├── assembleHar → .har 文件 (模块)
└── assembleApp → .app 文件 (签名发布)
9.2 产物结构对比
| 对比项 | iOS | OHOS |
|---|---|---|
| 最终产物 | .ipa | .hap / .app |
| 引擎包 | Flutter.framework | flutter.har |
| Dart 代码 | App.framework | rawfile/flutter_assets/ |
| 原生库 | .dylib / .framework | .so (libflutter.so) |
| 插件包 | .framework / .xcframework | .har / .hsp |
| 依赖管理 | CocoaPods / SPM | ohpm |
| 构建工具 | xcodebuild | Hvigor |
十、关系总结图
scss
┌──────────────────────────────────────────────────────────────┐
│ │
│ 包含关系 (从外到内): │
│ │
│ OHOS 进程 │
│ └── FlutterAbility (OHOS 宿主 UIAbility) │
│ └── FlutterEngine │
│ ├── Dart VM (进程唯一) │
│ │ └── Dart Isolate (可多个) │
│ ├── Skia / Impeller │
│ ├── Shell (OHOS 平台适配层) │
│ └── NAPI 桥接 (C++ ↔ ArkTS) │
│ │
│ 运行关系 (线程维度): │
│ │
│ OHOS Main Thread ═══ Flutter Platform Thread │
│ │ │ │
│ │ ├── NAPI 桥接调用 │
│ │ ├── 插件调用 (ArkTS) │
│ │ ├── 原生 ArkUI 交互 │
│ │ └── UIAbility 生命周期管理 │
│ │ │
│ Flutter UI Thread ─── Dart Root Isolate 运行于此 │
│ │ │ │
│ │ ├── Widget 构建 │
│ │ ├── 布局计算 │
│ │ └── 绘制指令生成 │
│ │ │
│ Flutter Raster Thread ─── GPU 光栅化于此 │
│ │ │ │
│ │ ├── Skia (OpenGL ES) │
│ │ └── Impeller (Vulkan) │
│ │ │
│ Flutter IO Thread ─── 资源加载/图片解码于此 │
│ │ │ │
│ │ ├── OHOSImageGenerator │
│ │ └── OhosWatchdog (非 Debug) │
│ │ │
│ Dart VM 线程池 ─── spawned Isolate 运行于此 │
│ │
│ 通信路径: │
│ │
│ Dart ←→ C++ Engine ←→ NAPI ←→ ArkTS │
│ │
└──────────────────────────────────────────────────────────────┘
十一、常见误区澄清
误区 1:Flutter 的 UI Thread 就是 OHOS 的 Main Thread
错!
- Flutter UI Thread 是单独的 pthread,专门运行 Dart 代码
- Flutter Platform Thread 才是 OHOS Main Thread
- 在 Dart 代码里调用 Platform Channel 时,消息从 UI Thread 通过 NAPI 发送到 Platform Thread(即 OHOS Main Thread)
误区 2:OHOS 端用 JNI 桥接原生代码
错!
- OHOS 端使用 NAPI (N-API) 而非 JNI
- NAPI 是 Node.js N-API 规范的实现,提供 C/C++ 与 ArkTS 的互操作
PlatformViewOHOSNapi暴露了 80+ 个 NAPI 方法- iOS 使用 Objective-C Runtime,Android 使用 JNI,OHOS 使用 NAPI
误区 3:OHOS 端的 FlutterAbility 等同于 iOS 的 FlutterViewController
错!
FlutterAbility对应的是FlutterAppDelegate(应用级别),不是FlutterViewController(视图级别)- OHOS 中
FlutterView+FlutterEntry才更接近FlutterViewController的角色 - OHOS 使用 Stage 模型,UIAbility 负责生命周期,Page 负责 UI 展示
误区 4:OHOS 端用 Metal 渲染
错!
- OHOS 不支持 Metal(Apple 专有)
- OHOS 支持 OpenGL ES + Skia 和 Vulkan + Impeller 两种渲染管线
- 默认使用 OpenGL ES + Skia,可通过配置启用 Vulkan + Impeller
- 渲染表面通过 XComponent 的 OHNativeWindow 提供
误区 5:OHOS 端的 VSync 和 iOS 一样使用 CADisplayLink
错!
- OHOS 使用
OH_NativeVSyncAPI - 额外支持 动态 VSync (
OH_NativeVSync_DVSyncSwitch) - 支持 帧率投票 (
OhosVsyncVotingMgr),可根据场景动态调整帧率 - 支持 帧缓存 机制,低刷新率时减少卡顿
误区 6:多个 FlutterEngine 就有多个 Dart VM
错!(与 iOS 一致)
- 一个 OHOS 进程中只有一个 Dart VM
- 多个 FlutterEngine 共享同一个 Dart VM
- 每个 FlutterEngine 有自己独立的 Root Isolate
- 使用
FlutterEngineGroup/nativeSpawn可以高效创建多引擎
误区 7:帧缓存是在低刷新率屏幕上启用的
错!
- 帧缓存 (
enable_frame_cache) 在 高于 60Hz 的屏幕上才启用 - 条件判断:
vsync_period < 15000000ns(即 VSync 周期小于 15ms,对应 > 66.7fps) - 在 120Hz 屏幕上,VSync 周期约 8.33ms < 15ms,所以启用
- 帧缓存会缓存一帧,牺牲一帧延迟换取渲染平滑度
- 在 60Hz 屏幕上(VSync 周期 16.67ms > 15ms),不启用帧缓存
误区 8:XComponent 在 FlutterView.ets 中创建
错!
- XComponent 实际在 FlutterPage.ets 中创建,通过
XComponent({ id: viewId, type: SURFACE, libraryname: 'flutter' })声明 - FlutterView.ets 是逻辑管理层,负责管理 ViewportMetrics、避让区域、引擎关联等
- FlutterPage.ets 的 XComponent 回调(
onLoad/onDestroy)触发 FlutterView 的onSurfaceCreated()/onSurfaceDestroyed()
十二、鸿蒙端特有能力
12.1 帧率投票机制 (LTPO)
帧率投票是 OHOS 端与 LTPO 屏幕深度配合的核心优化能力。完整投票场景:
yaml
┌──────────────────────────────────────────────────────────┐
│ 帧率投票场景 │
├──────────────────┬────────────┬──────────────────────────┤
│ 场景 │ 目标帧率 │ 触发方式 │
├──────────────────┼────────────┼──────────────────────────┤
│ 触摸按下 │ 120 FPS │ VsyncVotingTouchValue │
│ 触摸抬起 <100ms │ 120 FPS │ 快速操作延续高帧率 │
│ 触摸抬起 >3s │ 60 FPS │ 长时间静止过渡降频 │
│ Flutter 动画中 │ 90-120 FPS │ nativeAnimationVoting │
│ 视频播放中 │ 匹配视频帧率│ nativeVideoVoting │
│ PlatformView 存在 │ 120 FPS │ 平台视图需要高刷 │
│ 静态界面 │ 30 FPS │ 无交互时自动降频省电 │
│ 快速动画 │ 配置帧率 │ 根据动画速度动态投票 │
├──────────────────┼────────────┼──────────────────────────┤
│ 降频保护 │ 保持高帧率 │ 切换前保持 4 个 VSync │
│ │ 4 帧 │ (DelayFrameRateDrop) │
└──────────────────┴────────────┴──────────────────────────┘
投票 API:
OH_NativeVSync_SetExpectedFrameRateRange({
min: 30,
max: 120,
expected: <voted_fps>
})
12.2 避让区域 (AvoidArea)
OHOS 特有的窗口避让区域概念,FlutterView 自动处理。源码中获取四种避让区域并映射到 ViewportMetrics:
makefile
屏幕布局示意:
┌──────────────────────────────────┐
│ 状态栏 (TYPE_SYSTEM) │ ← systemAvoidArea
│ → physicalViewPaddingTop │
├──────────────────────────────────┤
│ │
│ Flutter 可用渲染区域 │
│ │
│ ← systemGestureInsetLeft │ ← gestureAvoidArea (TYPE_SYSTEM_GESTURE)
│ │ 两侧边缘手势区域
│ Right → │
│ │
├──────────────────────────────────┤
│ 导航指示条/AI Bar │ ← navigationAvoidArea
│ (TYPE_NAVIGATION_INDICATOR) │ (注意: 不是 TYPE_NAVIGATION)
│ → physicalViewPaddingBottom │
│ → systemGestureInsetBottom │
└──────────────────────────────────┘
键盘弹出时:
┌──────────────────────────────────┐
│ Flutter 可用渲染区域 │
│ (自动缩小) │
├──────────────────────────────────┤
│ 键盘区域 (TYPE_KEYBOARD) │ ← keyboardAvoidArea
│ → physicalViewInsetBottom │
│ (覆盖导航指示条区域) │
└──────────────────────────────────┘
四种避让区域到 ViewportMetrics 的映射关系:
| 避让区域类型 | AvoidAreaType | 映射到 ViewportMetrics |
|---|---|---|
| 状态栏/系统区域 | TYPE_SYSTEM |
physicalViewPaddingTop/Bottom/Left/Right |
| 导航指示条 | TYPE_NAVIGATION_INDICATOR |
physicalViewPaddingBottom, systemGestureInsetBottom |
| 系统手势区域 | TYPE_SYSTEM_GESTURE |
systemGestureInsetTop/Left/Bottom/Right |
| 键盘区域 | TYPE_KEYBOARD |
physicalViewInsetTop/Left/Bottom/Right |
12.3 无障碍 (Accessibility)
OHOS 端的无障碍实现桥接到 ArkUI 无障碍框架:
scss
Dart SemanticsNode
↓
C++ OhosSemanticsTree
├── OhosSemanticsNode (语义节点)
└── OhosSemanticsBridge (桥接)
↓ NAPI
ArkUI Accessibility Framework
├── FindAccessibilityNodeInfosById()
├── ExecuteAccessibilityAction()
└── 多实例 XComponent 无障碍 (API 15+)
12.4 字体管理
OHOS 端使用 SkFontMgr_OHOS 进行系统字体管理,支持:
InitializeSystemFont()--- 初始化系统字体ReloadSystemFonts()--- 热重载字体nativeCheckAndReloadFont()--- 检查并重新加载字体nativeSetFontWeightScale()--- 设置字体粗细缩放
12.5 键盘映射 (RawKeyEventDataOhos)
OHOS 端通过 raw_keyboard_ohos.dart 实现键盘事件映射,定义 OHOS 专用键码常量:
| 键码常量 | 值 | 说明 |
|---|---|---|
| KEYCODE_ALT_LEFT / RIGHT | 2045 / 2046 | Alt 键 |
| KEYCODE_SHIFT_LEFT / RIGHT | 2047 / 2048 | Shift 键 |
| KEYCODE_CTRL_LEFT / RIGHT | 2072 / 2073 | Ctrl 键 |
| KEYCODE_CAPS_LOCK | 2074 | 大小写锁定 |
| KEYCODE_SCROLL_LOCK | 2075 | 滚动锁定 |
| KEYCODE_NUM_LOCK | 2102 | 小键盘锁 |
| KEYCODE_FUNCTION | 2078 | 功能键 |
RawKeyEventDataOhos 继承 RawKeyEventData,通过 LogicalKeyboardKey.ohosPlane (0x01900000000) 映射物理键。keyboard_key.g.dart 中定义了 OHOS 平台专用键位。
十三、实际影响与性能调优启示
| 场景 | 涉及组件 | OHOS 端优化方向 |
|---|---|---|
| 界面卡顿 | UI Thread (Dart) | 减少 build() 复杂度,使用 const Widget |
| 光栅化卡顿 | Raster Thread | 减少 saveLayer、clipPath;考虑启用 Impeller (Vulkan) |
| 平台通信慢 | NAPI 桥接 | 减少 Channel 调用频率,批量传输,使用 BinaryCodec |
| 图片加载慢 | IO Thread / OHOSImageGenerator | 预缓存、降低分辨率、使用 precacheImage |
| 内存爆炸 | Dart VM (Isolate Heap) | 控制 Isolate 数量、及时释放大对象 |
| 原生插件阻塞 | Platform Thread (Main Thread) | ArkTS 插件内部使用 TaskPool 处理耗时逻辑 |
| App 启动慢 | Engine 初始化 + Dart VM 启动 | 预热 Engine(提前调用 FlutterEngine.init()) |
| 功耗过高 | VSync / 渲染 | 利用帧率投票降频,静态界面降至 30Hz |
| 刷新率不匹配 | VsyncWaiterOHOS | 启用动态 VSync (DVSyncSwitch),适配高刷屏 |
| 低内存警告 | 系统回调 | nativeSetQosOnLowMemory() 降低线程优先级 |
十四、版本更新与已知修复 (3.35.7-ohos-0.0.1-canary1)
基于 CHANGELOG_OHOS.md,当前版本主要修复包括:
| 修复项 | 说明 |
|---|---|
| Rect.fromLTRB 显示问题 | 修复矩形绘制显示异常 |
| flutter clean (Windows) | 解决无法正确删除 build 目录和 oh_modules 的问题 |
| gen_snapshot 路径 (Mac ARM64) | 修复 ARM64 Mac 上构建时 gen_snapshot 路径错误 |
| Dart 跟踪模式卡顿 | 修复开启 Dart trace 时应用卡顿 |
| 文本输入键盘缩回 | 解决 3.35 版本中 TextField 键盘无法缩回 |
| 剪切后粘贴失败 | 修复剪切操作后无法粘贴 |
| OHOS build 文件夹 | 修复 flutter build 无法生成指定文件夹 |
| Android Studio 断点 | 解决部分断点无法命中的问题 |
十五、关键源码路径索引
| 类别 | 文件路径 |
|---|---|
| 引擎入口 | engine/src/flutter/shell/platform/ohos/ohos_main.cpp |
| Shell 持有者 | engine/src/flutter/shell/platform/ohos/ohos_shell_holder.cpp |
| NAPI 桥接 | engine/src/flutter/shell/platform/ohos/napi/platform_view_ohos_napi.cpp |
| 平台视图 (C++) | engine/src/flutter/shell/platform/ohos/platform_view_ohos.cpp |
| VSync 等待 | engine/src/flutter/shell/platform/ohos/vsync_waiter_ohos.cpp |
| VSync 投票管理 | engine/src/flutter/shell/platform/ohos/ohos_vsync_voting_mgr.cpp |
| 触摸处理 | engine/src/flutter/shell/platform/ohos/ohos_touch_processor.cpp |
| XComponent 适配 | engine/src/flutter/shell/platform/ohos/ohos_xcomponent_adapter.cpp |
| GL/Skia 表面 | engine/src/flutter/shell/platform/ohos/ohos_surface_gl_skia.cpp |
| Vulkan/Impeller 表面 | engine/src/flutter/shell/platform/ohos/ohos_surface_vulkan_impeller.cpp |
| 外部纹理 (GL) | engine/src/flutter/shell/platform/ohos/ohos_external_texture_gl.cpp |
| 原生窗口 | engine/src/flutter/shell/platform/ohos/surface/ohos_native_window.cpp |
| 无障碍桥接 | engine/src/flutter/shell/platform/ohos/accessibility/ohos_semantics_bridge.cpp |
| 文字排版 | engine/src/flutter/txt/src/txt/platform_ohos.cc |
| ArkTS FlutterAbility | engine/.../flutter_embedding/.../embedding/ohos/FlutterAbility.ets |
| ArkTS FlutterEntry | engine/.../flutter_embedding/.../embedding/ohos/FlutterEntry.ets |
| ArkTS 代理 | engine/.../flutter_embedding/.../embedding/ohos/FlutterAbilityAndEntryDelegate.ets |
| ArkTS FlutterEngine | engine/.../flutter_embedding/.../embedding/engine/FlutterEngine.ets |
| ArkTS FlutterEngineGroup | engine/.../flutter_embedding/.../embedding/engine/FlutterEngineGroup.ets |
| ArkTS FlutterNapi | engine/.../flutter_embedding/.../embedding/engine/FlutterNapi.ets |
| ArkTS FlutterView | engine/.../flutter_embedding/.../view/FlutterView.ets |
| ArkTS FlutterPage | engine/.../flutter_embedding/.../embedding/ohos/FlutterPage.ets |
| ArkTS 生命周期通道 | engine/.../flutter_embedding/.../systemchannels/LifecycleChannel.ets |
| ArkTS 平台通道 | engine/.../flutter_embedding/.../systemchannels/PlatformChannel.ets |
| 平台检测 | packages/flutter/lib/src/foundation/_platform_io.dart |
| 键盘映射 | packages/flutter/lib/src/services/raw_keyboard_ohos.dart |
| 平台视图事件 | packages/flutter/lib/src/services/platform_views.dart |
| OHOS 构建器 | packages/flutter_tools/lib/src/ohos/ohos_builder.dart |
| Hvigor 工具 | packages/flutter_tools/lib/src/ohos/hvigor.dart |
| 构建目标 | packages/flutter_tools/lib/src/build_system/targets/ohos.dart |
| 构建系统 | engine/src/flutter/shell/platform/ohos/BUILD.gn |
总结: Flutter 在鸿蒙端的核心架构与 iOS 端保持一致(四线程模型 + Dart VM + Platform Channel),但在平台适配层有显著差异:使用 NAPI 替代 Objective-C Runtime 进行原生桥接,使用 XComponent + OHNativeWindow 替代 CAMetalLayer 提供渲染表面,使用 OH_NativeVSync 替代 CADisplayLink 实现帧同步,并通过 UIAbility Stage 模型管理应用生命周期。鸿蒙端还引入了帧率投票、动态 VSync、QoS 线程调度等独有的性能优化能力。