前言
Flutter 是 Google 推出的跨平台 UI 框架,最初只支持 iOS 和 Android。随着 HarmonyOS 的崛起,Flutter 也能在鸿蒙系统上运行了。这背后到底是怎么实现的呢?本文将从源码层面进行解析。
一、核心原理:Flutter 分层架构
要理解 Flutter 如何在 HarmonyOS 上运行,首先需要了解 Flutter 的架构。Flutter 采用分层设计,从上到下分为三层:
┌─────────────────────────────────┐
│ Framework 层(Dart) │ ← Flutter 代码
├─────────────────────────────────┤
│ Engine 层(C++) │ ← 渲染引擎(Impeller)
├─────────────────────────────────┤
│ Embedder 层(平台相关) │ ← 与操作系统交互(调用 HarmonyOS 原生 API)
└─────────────────────────────────┘
前面两层完全复用现有Dart和C++代码,而 Embedder 层则是为 HarmonyOS 定制的。
关键点:Embedder 层
Embedder 层是 Flutter 能够跨平台运行的关键。它负责:
-
创建和管理窗口
-
处理输入事件
-
调用系统 API
-
管理渲染 Surface
**不同平台有不同的 Embedder 实现: **
-
Android:
platform_view_android.cc -
iOS:
platform_view_ios.mm -
HarmonyOS:
platform_view_ohos.cpp
cc和cpp是标准的C++语言代码后缀
鸿蒙的系统API是C++ 实现的,所以鸿蒙platform_view 使用C++实现进行调用最方便**
二、HarmonyOS Embedder 的核心实现
让我们看看 HarmonyOS Embedder 的核心代码结构:
2.1 平台视图(PlatformViewOHOS)
这是 HarmonyOS Embedder 的核心类,位于:
engine/src/flutter/shell/platform/ohos/platform_view_ohos.cpp
class PlatformViewOHOS final : public PlatformView {
public:
PlatformViewOHOS(PlatformView::Delegate& delegate,
const flutter::TaskRunners& task_runners,
const std::shared_ptr<PlatformViewOHOSNapi>& napi_facade,
const std::shared_ptr<flutter::OHOSContext>& ohos_context);
// 通知窗口创建
void NotifyCreate(fml::RefPtr<OHOSNativeWindow> native_window);
// 更新显示尺寸
void UpdateDisplaySize(int width, int height);
// 分发平台消息
void DispatchPlatformMessage(std::string name, void* message, ...);
private:
std::shared_ptr<OHOSContext> ohos_context_; // HarmonyOS 图形上下文
std::shared_ptr<PlatformViewOHOSNapi> napi_facade_; // NAPI装饰器(NAPI 是 HarmonyOS 提供的 JavaScript 接口, 用于调用 HarmonyOS 系统 API
std::unique_ptr<OHOSSurface> ohos_surface_; // HarmonyOS 渲染 Surface, surface 是渲染的目标画布, 可以是窗口, 也可以是离屏缓冲区
};
**这个类做了什么? **
-
继承自
PlatformView(Flutter 的通用平台视图接口) -
持有 HarmonyOS 的图形上下文
OHOSContext -
持有 NAPI装饰器
PlatformViewOHOSNapi(用于调用 HarmonyOS 原生 API) -
管理渲染 Surface
OHOSSurface
2.2 Shell 持有者(OHOSShellHolder)
Shell 是 Flutter 引擎的核心,负责管理 Flutter 应用的生命周期、渲染循环、事件处理等, OHOSShellHolder 负责创建和管理 Shell:
class OHOSShellHolder {
public:
// 构造函数
// settings: Flutter 引擎启动参数(如是否启用 Impeller、日志级别等)
// napi_facade: 与 HarmonyOS 原生层交互的 NAPI 装饰器
// platform_loop: HarmonyOS 平台线程的 looper,用于投递平台任务
OHOSShellHolder(const flutter::Settings& settings,
std::shared_ptr<PlatformViewOHOSNapi> napi_facade,
void* platform_loop);
// 析构函数:确保 Shell 安全退出并释放所有资源
~OHOSShellHolder();
// 启动 Flutter 引擎,加载 Dart 代码并开始渲染
// hap_asset_provider: HarmonyOS HAP 包资源提供器,用于读取 assets、fonts、kernel_blob 等
// entrypoint: Dart 入口函数名(默认为 main)
// libraryUrl: Dart 库 URI(如 package:my_app/main.dart)
// entrypoint_args: 传给 Dart main 的命令行参数列表
void Launch(std::unique_ptr<OHOSAssetProvider> hap_asset_provider,
const std::string& entrypoint,
const std::string& libraryUrl,
const std::vector<std::string>& entrypoint_args);
// 优雅地停止 Flutter Shell,等待所有任务完成后退出
void Shutdown();
// 获取 PlatformViewOHOS 的弱引用,用于在平台线程安全地访问平台视图
fml::WeakPtr<PlatformViewOHOS> GetPlatformView();
// 设置应用生命周期回调,供 HarmonyOS 通知 Flutter 前后台切换
void SetLifecycleHandler(std::function<void(AppLifecycleState)> handler);
// 设置平台消息回调,供 HarmonyOS 主动发消息到 Dart 侧
void SetPlatformMessageHandler(
std::function<void(const std::string& channel,
const std::vector<uint8_t>& message,
std::function<void(std::vector<uint8_t>)> reply)> handler);
// 向 Dart 侧发送平台消息,支持异步回调
void SendPlatformMessage(const std::string& channel,
const std::vector<uint8_t>& message,
std::function<void(std::vector<uint8_t>)> reply = nullptr);
// 通知 Flutter 引擎窗口尺寸变化,触发重新布局
void NotifyViewportMetricsChanged(const ViewportMetrics& metrics);
// 通知 Flutter 引擎内存压力,触发 Dart 侧 GC 或资源释放
void NotifyLowMemoryWarning();
// 获取当前 Shell 的运行状态
enum class ShellState { kNotStarted, kRunning, kShuttingDown, kStopped };
ShellState GetShellState() const;
// 返回当前线程安全的 Shell 指针,仅用于调试或测试
Shell* GetShellUnsafe() const { return shell_.get(); }
private:
// 创建并配置 Flutter Shell,内部调用 Shell::Create
void CreateShell(const flutter::Settings& settings,
std::unique_ptr<OHOSAssetProvider> asset_provider);
// 初始化平台任务执行器,将 HarmonyOS 平台任务映射到 Flutter 的任务队列
void SetupTaskRunners(void* platform_loop);
// 注册 HarmonyOS 平台视图到 Shell,完成平台桥接
void RegisterPlatformView();
// 加载 Dart AOT 或 Kernel,决定运行模式(Release/Profile 使用 AOT,Debug 使用 Kernel)
void LoadDartCode(const std::string& entrypoint,
const std::string& libraryUrl,
const std::vector<std::string>& entrypoint_args);
// 释放所有资源,顺序:PlatformView → Shell → TaskRunners
void Teardown();
private:
std::unique_ptr<Shell> shell_; // Flutter 引擎核心
std::shared_ptr<PlatformViewOHOSNapi> napi_facade_; // NAPI 装饰器
fml::WeakPtrFactory<OHOSShellHolder> weak_factory_; // 弱引用工厂,防止悬空指针
ShellState state_ = ShellState::kNotStarted; // 当前 Shell 状态
flutter::TaskRunners task_runners_; // 跨平台任务队列(UI/GPU/IO/Platform)
std::mutex state_mutex_; // 保护 state_ 的线程安全
};
三、图形渲染适配
Flutter 在 HarmonyOS 上支持三种渲染方式:
3.1 鸿蒙三种渲染方式
enum class OHOSRenderingAPI {
kSoftware, // 软件渲染, 基于 CPU 进行渲染, 性能较低, 不依赖于 GPU,适用于简单场景。
kOpenGLES, // OpenGL ES 渲染(Skia), 基于 OpenGL ES 进行渲染, 性能较高, 依赖于 GPU, 适用于复杂场景。
kImpellerVulkan, // Vulkan 渲染(Impeller), 基于 Vulkan 进行渲染, 性能最高, 依赖于 GPU, 适用于需要高性能渲染的场景。
};
在 platform_view_ohos.cpp 中,根据渲染方式创建不同的Surface:
std::unique_ptr<OHOSSurface> OhosSurfaceFactoryImpl::CreateSurface() {
switch (ohos_context_->RenderingApi()) {
case OHOSRenderingAPI::kSoftware:
return std::make_unique<OHOSSurfaceSoftware>(ohos_context_); // 软件渲染, 基于 CPU 进行渲染, 性能较低, 不依赖于 GPU,适用于简单场景。
case OHOSRenderingAPI::kOpenGLES:
return std::make_unique<OhosSurfaceGLSkia>(ohos_context_); // OpenGL ES 渲染(Skia), 基于 OpenGL ES 进行渲染, 性能较高, 依赖于 GPU, 适用于复杂场景。
case flutter::OHOSRenderingAPI::kImpellerVulkan:
return std::make_unique<OHOSSurfaceVulkanImpeller>(ohos_context_); // Vulkan 渲染(Impeller), 基于 Vulkan 进行渲染, 性能最高, 依赖于 GPU, 适用于需要高性能渲染的场景。
default:
return nullptr;
}
}
3.2 原生窗口(OHOSNativeWindow)
HarmonyOS 的窗口系统通过 OHNativeWindow 暴露给 Flutter:
class OHOSNativeWindow : public fml::RefCountedThreadSafe<OHOSNativeWindow> {
public:
Handle Gethandle() const; // 获取 HarmonyOS 原生窗口句柄
bool IsValid() const; // 检查窗口是否有效
SkISize GetSize() const; // 获取窗口尺寸
private:
Handle window_; // OHNativeWindow*
};
**渲染流程: **
Flutter Engine
↓
PlatformViewOHOS
↓
OHOSSurface(根据渲染方式创建不同的Surface)
↓
OHOSNativeWindow(HarmonyOS 原生窗口)
↓
HarmonyOS 图形系统
四、输入事件处理
因为事件处理需要在渲染完成后(VSync同步流程)才能触发, 否则会导致事件处理与渲染不一致的问题。
4.1 VSync 同步
VSync(垂直同步)信号是渲染的关键,它是每次屏幕刷新周期开始时发送的信号,用于同步渲染和显示。
Flutter 需要等待系统的 VSync 信号,才能触发下一帧渲染。
class VsyncWaiterOHOS final : public VsyncWaiter {
public:
explicit VsyncWaiterOHOS(const flutter::TaskRunners& task_runners,
std::shared_ptr<bool>& enable_frame_cache);
private:
OH_NativeVSync* vsync_handle_; // HarmonyOS VSync 句柄
void AwaitVSync() override; // 等待 VSync 信号
static void OnVsyncFromOHOS(long long timestamp, void* data); // 接收 HarmonyOS VSync 信号, 通知 Flutter Engine 触发下一帧渲染
};
**工作流程: **
HarmonyOS VSync 信号
↓
VsyncWaiterOHOS::OnVsyncFromOHOS
↓
通知 Flutter Engine
↓
触发下一帧渲染
↓
渲染完成
↓
触发事件处理
4.2 触摸事件处理
HarmonyOS 的输入事件需要转换为 Flutter 的事件格式:
触摸事件通过 OhosTouchProcessor 处理:
class OhosTouchProcessor {
public:
// 处理 HarmonyOS 触摸事件
void ProcessTouchEvent(const OH_NativeXComponent_TouchEvent* event);
private:
// 转换为 Flutter 触摸事件格式
std::vector<PointerData> ConvertToFlutterTouchEvents(
const OH_NativeXComponent_TouchEvent* event);
};
五、平台消息通信
Flutter 与 HarmonyOS 的通信通过 Platform Channel 实现:
5.1 NAPI 装饰器(PlatformViewOHOSNapi)
NAPI(Native API)是 HarmonyOS 提供的原生 API 接口:
class PlatformViewOHOSNapi {
public:
// 发送平台消息到 HarmonyOS
void SendPlatformMessage(const std::string& channel,
const std::vector<uint8_t>& message);
// 接收来自 HarmonyOS 的平台消息
void SetPlatformMessageHandler(
std::function<void(const std::string&, const std::vector<uint8_t>&)> handler);
private:
napi_env env_; // NAPI 环境
};
5.2 消息处理流程
Flutter 代码(Dart)
↓
MethodChannel.invokeMethod
↓
PlatformViewOHOS::DispatchPlatformMessage
↓
PlatformViewOHOSNapi::SendPlatformMessage
↓
HarmonyOS 原生代码(ArkTS/C++)
↓
返回结果
↓
Flutter 接收响应
六、完整的工作流程
让我们把所有部分串联起来,看看 Flutter 应用在 HarmonyOS 上是如何运行的:
6.1 初始化流程
1. HarmonyOS 应用启动
↓
2. 调用 OhosMain::NativeInit(NAPI 入口)
↓
3. 创建 OHOSShellHolder
↓
4. 创建 PlatformViewOHOS
↓
5. 创建 OHOSContext(图形上下文)
↓
6. 创建 OHOSSurface(渲染表面)
↓
7. 创建 Flutter Shell(引擎)
↓
8. 加载 Dart 代码
↓
9. 开始渲染
6.2 渲染流程
1. Dart 代码构建 Widget 树
↓
2. Framework 层生成 Layer 树
↓
3. Engine 层生成 Scene
↓
4. Impeller 渲染引擎绘制
↓
5. 通过 OHOSSurface 提交绘制指令
↓
6. OHOSNativeWindow 接收绘制结果
↓
7. HarmonyOS 图形系统显示到屏幕
6.3 事件处理流程
1. 用户触摸屏幕
↓
2. HarmonyOS 接收触摸事件
↓
3. OhosTouchProcessor 处理
↓
4. 转换为 Flutter 触摸事件格式
↓
5. PlatformViewOHOS 分发事件
↓
6. Framework 层处理事件
↓
7. Widget 响应用户操作
七、关键代码示例
7.1 创建 HarmonyOS Embedder
// 创建图形上下文
std::unique_ptr<OHOSContext> CreateOHOSContext(
const flutter::TaskRunners& task_runners,
OHOSRenderingAPI rendering_api,
bool enable_vulkan_validation,
bool enable_opengl_gpu_tracing,
bool enable_vulkan_gpu_tracing) {
switch (rendering_api) {
case OHOSRenderingAPI::kSoftware:
return std::make_unique<OHOSContext>(OHOSRenderingAPI::kSoftware);
case OHOSRenderingAPI::kOpenGLES:
return std::make_unique<OhosContextGLSkia>(OHOSRenderingAPI::kOpenGLES,
task_runners);
case OHOSRenderingAPI::kImpellerVulkan:
return std::make_unique<OHOSContextVulkanImpeller>(
enable_vulkan_validation, enable_vulkan_gpu_tracing);
default:
return nullptr;
}
}
// 创建平台视图
PlatformViewOHOS::PlatformViewOHOS(
PlatformView::Delegate& delegate,
const flutter::TaskRunners& task_runners,
const std::shared_ptr<PlatformViewOHOSNapi>& napi_facade,
const std::shared_ptr<flutter::OHOSContext>& ohos_context)
: PlatformView(delegate, task_runners),
napi_facade_(napi_facade),
ohos_context_(ohos_context) {
// 创建 Surface 工厂
surface_factory_ = std::make_shared<OhosSurfaceFactoryImpl>(ohos_context_);
// 创建渲染 Surface
ohos_surface_ = surface_factory_->CreateSurface();
// 预加载 GPU Surface(加速首帧渲染)
task_runners_.GetRasterTaskRunner()->PostDelayedTask(
[surface = ohos_surface_]() { surface->PrepareGpuSurface(); },
fml::TimeDelta::FromMicroseconds(1000));
}
7.2 通知窗口创建
void PlatformViewOHOS::NotifyCreate(
fml::RefPtr<OHOSNativeWindow> native_window) {
FML_LOG(INFO) << "NotifyCreate start";
// 缓存原生窗口
native_window_ = native_window;
// 通知 Surface 窗口已创建
ohos_surface_->SetNativeWindow(native_window);
// 获取窗口尺寸
SkISize size = native_window->GetSize();
// 更新视口尺寸
UpdateDisplaySize(size.width(), size.height());
// 通知 Flutter 引擎窗口已创建
NotifyCreated();
}
7.3 处理平台消息
void PlatformViewOHOS::DispatchPlatformMessage(
std::string name,
void* message,
int messageLength,
int responseId) {
// 创建平台消息
fml::MallocMapping buffer = fml::MallocMapping(
static_cast<const uint8_t*>(message), messageLength);
auto platform_message = std::make_unique<PlatformMessage>(
name,
std::move(buffer),
responseId,
fml::TimePoint::Now());
// 分发到 Flutter 引擎
DispatchPlatformMessage(std::move(platform_message));
}
八、为什么 Flutter 能在 HarmonyOS 上运行?
通过上面的代码分析,我们可以总结出以下几个关键原因:
8.1 架构设计优势
Flutter 的分层架构设计使得 Embedder 层可以独立适配不同平台:
-
Framework 层和 Engine 层是平台无关的
-
只有 Embedder 层需要针对不同平台实现
8.2 HarmonyOS 提供的开放接口
HarmonyOS 提供了丰富的原生 API,使得 Flutter 可以:
-
通过
OHNativeWindow获取窗口句柄 -
通过
OH_NativeVSync获取 VSync 信号 -
通过 NAPI 调用系统能力
-
通过 XComponent 组件集成 Flutter 视图
8.3 图形接口兼容
HarmonyOS 支持标准的图形接口:
-
OpenGL ES:Skia 渲染引擎可以直接使用
-
Vulkan:Impeller 渲染引擎可以直接使用
-
NativeWindow:提供了跨平台的窗口抽象
8.4 社区共同努力
-
华为官方和 Flutter 社区共同维护
flutter_flutter项目 -
基于 Flutter Engine 源码进行适配
-
提供完整的开发工具链
从代码层面看,核心就是实现了 PlatformViewOHOS、OHOSShellHolder、OHOSContext 等类,将 Flutter Engine 与 HarmonyOS 系统连接起来。
**一句话总结:Flutter 通过实现 HarmonyOS 专属的 Embedder 层,将 Flutter Engine 与 HarmonyOS 的窗口系统、图形系统、输入系统对接,从而实现了跨平台运行。 **