摘要:本文作为《Flutter 与开源鸿蒙实战》的续篇,聚焦于 高级集成场景,包括自定义 Embedder 实现原理、跨设备协同(Continuation)、原子化服务封装、状态管理与 OpenHarmony 数据模型联动、以及 CI/CD 自动化构建流程。内容面向中高级开发者,旨在打通 Flutter 应用在 OpenHarmony 生态中的“最后一公里”。

在上一篇中,我们完成了 Flutter 在 OpenHarmony 上的基础运行环境搭建,并实现了简单的设备信息插件。然而,要真正构建生产级应用,还需解决以下核心问题:
本篇将逐一攻克这些难题。
Embedder 是 Flutter Engine 与宿主平台之间的桥梁。在 Android 中是 FlutterActivity,在 iOS 中是 FlutterViewController。在 OpenHarmony 中,我们需要实现一个 OHOS Embedder,负责:
// ohos_embedder.cc
#include "flutter/shell/platform/embedder/embedder.h"
#include "surface_ohos.h" // 自定义 Surface
#include "event_handler.h" // 事件分发
static FlutterEngine g_engine = nullptr;
void OnFlutterPlatformMessage(const FlutterPlatformMessage* message,
void* user_data) {
if (strcmp(message->channel, "com.example/softbus") == 0) {
// 转发到 OpenHarmony NAPI 模块处理分布式通信
HandleSoftBusMessage(message);
}
}
bool InitializeFlutterEngine() {
FlutterRendererConfig config = {};
config.type = kOpenGL;
config.open_gl.struct_size = sizeof(config.open_gl);
config.open_gl.make_current = [](void*) { return true; };
config.open_gl.clear_current = [](void*) {};
config.open_gl.fbo_callback = [](void*) { return 0; };
config.open_gl.present_with_info = [](void*, const FlutterPresentInfo* info) {
// 调用 OHOS 图形子系统提交帧
OHOS::Surface::Present(info->frame_interval);
};
FlutterProjectArgs args = {};
args.assets_path = "/data/app/assets";
args.icu_data_path = "/system/etc/icu/icudt73l.dat";
args.platform_message_callback = OnFlutterPlatformMessage;
FlutterEngineResult result = FlutterEngineRun(
FLUTTER_ENGINE_VERSION, &config, &args, nullptr, &g_engine);
return result == kSuccess;
}提示:OpenHarmony 的图形子系统基于 Rosen(自研窗口系统),需通过
RSTransaction提交绘制命令。
在 EntryAbility.ts 中:
import flutterEmbedder from './native/libflutter_embedder.so';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log('Flutter App onCreate');
flutterEmbedder.init(); // 初始化 Embedder
}
onDestroy(): void {
flutterEmbedder.shutdown(); // 释放 Engine
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// 获取窗口句柄并传给 Embedder
const winId = windowStage.getMainWindowSync().windowId;
flutterEmbedder.setWindowId(winId);
}
}OpenHarmony 的核心优势在于 分布式软总线(DSoftBus),可实现设备间低延迟、高可靠通信。
final channel = MethodChannel('dsoftbus');
Future<void> startDeviceDiscovery() async {
await channel.invokeMethod('startDiscovery', {'serviceType': 'smart_light'});
}
Future<void> sendDataToDevice(String deviceId, String data) async {
await channel.invokeMethod('sendData', {
'deviceId': deviceId,
'data': data,
});
}// dsoftbus_plugin.cpp
#include "softbus_client.h" // OpenHarmony 软总线 SDK
napi_value StartDiscovery(napi_env env, napi_callback_info info) {
// 解析参数
char serviceType[64];
// ... 从 JS 参数提取
// 调用 OpenHarmony DSoftBus API
int ret = PublishLNN(serviceType, OnDeviceFoundCallback);
if (ret != 0) {
// 错误处理
}
return nullptr;
}注意:需在
module.json5中申请ohos.permission.DISTRIBUTED_DATASYNC权限。
当用户从平板走到手机旁,应用自动迁移到手机继续操作。
注册迁移能力:
// EntryAbility.ts
import continuationManager from '@ohos.application.continuationManager';
continuationManager.on('continue', (want) => {
// 保存当前 Flutter 状态(如页面路径、表单数据)
const state = flutter.getState();
want.parameters = { flutterState: JSON.stringify(state) };
return true; // 允许迁移
});目标设备接收:
// 目标设备的 EntryAbility
onCreate(want: Want) {
if (want.parameters?.flutterState) {
const state = JSON.parse(want.parameters.flutterState);
flutter.restoreState(state); // 恢复 UI 状态
}
}Flutter 侧状态管理:
使用 Provider 或 Riverpod 将关键状态序列化为 JSON。
OpenHarmony 支持“免安装”服务卡片,Flutter 可作为服务 UI 提供者。
// module.json5
{
"abilities": [
{
"name": "LightControlService",
"type": "service",
"srcEntry": "./ets/LightControlService.ts",
"visible": true,
"skills": [
{ "entities": ["entity.system.home"], "actions": ["action.service.light"] }
]
}
]
}// LightControlService.ts
import flutterMiniApp from './flutter_mini/light_control';
export default class LightControlService extends ServiceExtensionAbility {
onConnect(want: Want): void {
// 启动轻量级 Flutter 引擎(仅渲染一个 Widget)
flutterMiniApp.renderToSurface(this.surfaceHandle);
}
}优势:用户无需安装完整 App,即可通过服务卡片控制设备。
@ohos.data.preferences 同步配置// flutter_preferences.dart
class OHOSPreferences {
static const _channel = MethodChannel('ohos/preferences');
static Future<void> setString(String key, String value) async =>
_channel.invokeMethod('setString', {'key': key, 'value': value});
static Future<String?> getString(String key) async =>
_channel.invokeMethod('getString', {'key': key});
}OpenHarmony 支持深色/浅色模式切换:
// 监听主题变化
import themeManager from '@ohos.app.ability.themeManager';
themeManager.on('themeChange', (theme) => {
flutter.sendTheme(theme.isDarkMode ? 'dark' : 'light');
});Flutter 侧:
void initPlatformState() {
const EventChannel('ohos/theme').receiveBroadcastStream().listen((theme) {
ThemeMode mode = theme == 'dark' ? ThemeMode.dark : ThemeMode.light;
context.read<ThemeBloc>().add(ThemeChanged(mode));
});
}#!/bin/bash
# 1. 编译 Flutter AOT
flutter build ohos --release
# 2. 复制产物到 ohos/assets
cp -r build/ohos/release/* ohos/src/main/resources/rawfile/
# 3. 使用 DevEco CLI 打包 HAP
devecostudio --build --project . --mode release
# 4. 安装到远程设备(通过 hdc)
hdc install outputs/default/oh_flutter_demo-unsigned.hapname: Build for OpenHarmony
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup DevEco CLI
run: |
wget https://.../devecostudio-cli.tar.gz
tar -xzf devecostudio-cli.tar.gz
echo "$PWD/devecostudio-cli/bin" >> $GITHUB_PATH
- name: Build & Test
run: ./scripts/build_and_test.shFrameTiming API 上报到 OpenHarmony HiLog。DevEco Profiler 与 Flutter Memory Dashboard。FlutterError.onError,将堆栈通过 NAPI 写入系统日志。Flutter 与 OpenHarmony 的集成已从“能否运行”迈向“如何高效开发”。尽管工具链仍在完善,但通过 Embedder 定制 + 插件封装 + 分布式能力对接,我们已能构建具备商业价值的应用。
下一步建议:
openharmony 标签附录:常用资源链接