Flutter跨平台FlutterEngineGroup鸿蒙化使用指南
FlutterEngineGroup插件在OpenHarmony中的应用 FlutterEngineGroup是OpenHarmony平台上的多引擎管理插件,支持在单个应用中创建和管理多个独立Flutter引擎实例。该插件通过资源共享和隔离机制优化性能,适用于复杂混合开发场景。使用前需配置DevEco Studio、JDK 17和Flutter SDK环境,通过Git引入依赖后,需在EntryAb

一、FlutterEngineGroup插件介绍
FlutterEngineGroup是OpenHarmony平台上的一个高级组件,它允许开发者在单个应用中管理多个Flutter引擎实例,实现更灵活、更高效的混合开发架构。通过FlutterEngineGroup,开发者可以在不同页面或模块中使用独立的Flutter引擎,实现资源隔离和性能优化。
核心功能特点:
- 多引擎管理:支持在单个应用中创建和管理多个Flutter引擎实例
- 资源共享:引擎之间共享资源,减少内存占用
- 灵活控制:可根据需求动态创建和销毁引擎
- 隔离性:不同引擎实例之间相互隔离,避免状态污染
- 高性能:优化的引擎启动和资源管理机制
二、环境搭建
在使用FlutterEngineGroup之前,需要确保已经完成以下环境配置:
- DevEco Studio:安装最新版本的DevEco Studio(推荐4.0+)
- JDK 17:配置JDK 17环境变量
- Flutter SDK:下载并配置OpenHarmony版本的Flutter SDK
- 环境变量:
export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn export PATH=/path/to/flutter_flutter/bin:$PATH export PATH=/path/to/ohos-sdk/ets/tools:$PATH
三、FlutterEngineGroup的引入与配置
由于FlutterEngineGroup是为OpenHarmony定制修改的版本,需要通过AtomGit以Git形式引入:
3.1 添加依赖
在OpenHarmony项目的pubspec.yaml文件中,添加FlutterEngineGroup的Git依赖:
dependencies:
flutter_engine_group:
git:
url: "https://atomgit.com/flutter-openharmony/flutter_engine_group"
path: "packages/flutter_engine_group/flutter_engine_group"
3.2 安装依赖
执行以下命令安装依赖:
flutter pub get
四、FlutterEngineGroup的使用步骤
4.1 EntryAbility配置
首先,需要将EntryAbility继承自UIAbility,并实现相关接口:
import { AbilityConstant, UIAbility, Want, window } from '@kit.AbilityKit';
import { common } from '@kit.ArkTS';
import { FlutterManager } from '@ohos/flutter_engine_group';
import type { ExclusiveAppComponent } from '@ohos/flutter_engine_group';
export default class EntryAbility extends UIAbility implements ExclusiveAppComponent<UIAbility> {
detachFromFlutterEngine(): void {
// 实现detachFromFlutterEngine方法
}
getAppComponent(): UIAbility {
return this;
}
static app?: EntryAbility;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
FlutterManager.getInstance().pushUIAbility(this);
EntryAbility.app = this;
}
onDestroy(): void | Promise<void> {
FlutterManager.getInstance().popUIAbility(this);
EntryAbility.app = undefined;
}
onWindowStageCreate(windowStage: window.WindowStage): void {
FlutterManager.getInstance().pushWindowStage(this, windowStage);
windowStage.loadContent('pages/MainPage');
}
onWindowStageDestroy() {
FlutterManager.getInstance().popWindowStage(this);
}
}
4.2 封装FlutterEngine的attach和detach操作
为了更好地管理FlutterEngine的生命周期,建议封装一个EngineBindings类:
import { common } from '@kit.ArkTS';
import { FlutterEngine, FlutterManager, MethodChannel, Options, engines, DartEntrypoint } from '@ohos/flutter_engine_group';
import { Log } from '@ohos.hilog';
import type { EngineBindingsDelegate } from './EngineBindingsDelegate';
export class EngineBindings implements DataModelObserver {
private engine?: FlutterEngine;
private channel?: MethodChannel;
private context: common.Context;
private delegate: EngineBindingsDelegate;
private flutterView: FlutterView;
constructor(context: common.Context, delegate: EngineBindingsDelegate) {
this.context = context;
this.delegate = delegate;
this.flutterView = FlutterManager.getInstance().createFlutterView(context);
}
getFlutterViewId() {
return this.flutterView.getId();
}
async attach() {
if (this.engine) {
Log.i("Multi->attach", "engine already exists");
return;
}
DataModel.instance.addObserver(this);
// 按顺序执行以下步骤
// 1. 检查加载器
await engines.checkLoader(this.context, []);
// 2. 创建并运行引擎
let options: Options = new Options(this.context)
.setDartEntrypoint(DartEntrypoint.createDefault());
this.engine = await engines.createAndRunEngineByOptions(options) ?? undefined;
if (!this.engine) {
throw new Error("Create engine failed.");
}
// 3. 通知引擎应用已恢复
this.engine.getLifecycleChannel()?.appIsResumed();
// 4. 附加到Ability
if (EntryAbility.app) {
this.engine.getAbilityControlSurface()?.attachToAbility(EntryAbility.app);
}
// 5. 将FlutterView附加到引擎
this.flutterView.attachToFlutterEngine(this.engine);
// 6. 注册插件
GeneratedPluginRegistrant.registerWith(this.engine);
// 7. 设置MethodChannel通信
this.setupMethodChannel();
}
detach() {
this.flutterView.detachFromFlutterEngine();
this.engine?.destroy();
DataModel.instance.removeObserver(this);
this.channel?.setMethodCallHandler(null);
}
private setupMethodChannel() {
if (!this.engine) return;
this.channel = new MethodChannel(this.engine, 'flutter_engine_channel');
this.channel.setMethodCallHandler((call, result) => {
// 处理Flutter发送的消息
switch (call.method) {
case 'getEngineInfo':
result.success({ 'engineId': this.engine?.getId() });
break;
default:
result.notImplemented();
}
});
}
// 实现DataModelObserver接口方法
onDataChange(key: string, value: any): void {
// 处理数据变化
}
}
4.3 在页面中使用FlutterEngineGroup
在OpenHarmony页面中,可以通过以下方式使用FlutterEngineGroup:
import { common } from '@kit.ArkTS';
import { Column, Log } from '@ohos.arkui.widget';
import { FlutterPage } from '@ohos/flutter_engine_group';
import { EngineBindings } from '../engine/EngineBindings';
import type { EngineBindingsDelegate } from '../engine/EngineBindingsDelegate';
@Entry()
@Component
struct SingleFlutterPage implements EngineBindingsDelegate {
@State viewId: string = "";
private context = getContext(this) as common.UIAbilityContext;
private engineBindings: EngineBindings = new EngineBindings(this.context, this);
onNext() {
router.pushUrl({ "url": "pages/MainPage" });
}
aboutToAppear() {
Log.i("Multi->aboutToAppear", "SingleFlutterPage");
this.viewId = this.engineBindings.getFlutterViewId();
Log.i("Multi->aboutToAppear", "SingleFlutterPage, id=" + this.viewId);
this.engineBindings.attach();
}
aboutToDisappear(): void {
this.engineBindings.detach();
}
build() {
Column() {
FlutterPage({ viewId: this.viewId, xComponentType: XComponentType.TEXTURE })
.backgroundColor(Color.Transparent)
.width('100%')
.height('100%')
}
}
}
4.4 Flutter与OpenHarmony通信
FlutterEngineGroup支持通过MethodChannel实现Flutter与OpenHarmony原生层的双向通信:
在Flutter端发送消息:
import 'package:flutter/services.dart';
class EngineCommunication {
static const MethodChannel _channel = MethodChannel('flutter_engine_channel');
// 获取引擎信息
static Future<Map<String, dynamic>?> getEngineInfo() async {
try {
final Map<dynamic, dynamic>? result = await _channel.invokeMethod('getEngineInfo');
return result?.cast<String, dynamic>();
} on PlatformException catch (e) {
print('Failed to get engine info: ${e.message}');
return null;
}
}
}
在OpenHarmony端接收消息:
private setupMethodChannel() {
if (!this.engine) return;
this.channel = new MethodChannel(this.engine, 'flutter_engine_channel');
this.channel.setMethodCallHandler((call, result) => {
// 处理Flutter发送的消息
switch (call.method) {
case 'getEngineInfo':
result.success({ 'engineId': this.engine?.getId() });
break;
case 'showMessage':
const message = call.arguments['message'];
this.showToast(message);
result.success('Message shown');
break;
default:
result.notImplemented();
}
});
}
五、完整示例
以下是一个完整的FlutterEngineGroup使用示例,展示了如何在OpenHarmony应用中管理多个Flutter引擎实例:
5.1 EngineBindingsDelegate接口
export interface EngineBindingsDelegate {
onNext(): void;
}
5.2 DataModel类
export interface DataModelObserver {
onDataChange(key: string, value: any): void;
}
export class DataModel {
private static instance: DataModel;
private observers: DataModelObserver[] = [];
private data: Map<string, any> = new Map();
private constructor() {}
static get instance() {
if (!DataModel.instance) {
DataModel.instance = new DataModel();
}
return DataModel.instance;
}
addObserver(observer: DataModelObserver) {
if (!this.observers.includes(observer)) {
this.observers.push(observer);
}
}
removeObserver(observer: DataModelObserver) {
const index = this.observers.indexOf(observer);
if (index > -1) {
this.observers.splice(index, 1);
}
}
setData(key: string, value: any) {
this.data.set(key, value);
this.notifyObservers(key, value);
}
getData(key: string): any {
return this.data.get(key);
}
private notifyObservers(key: string, value: any) {
this.observers.forEach(observer => {
observer.onDataChange(key, value);
});
}
}
5.3 多引擎管理页面
import { common } from '@kit.ArkTS';
import { Column, Text, Button, Log } from '@ohos.arkui.widget';
import { FlutterPage } from '@ohos/flutter_engine_group';
import { EngineBindings } from '../engine/EngineBindings';
import type { EngineBindingsDelegate } from '../engine/EngineBindingsDelegate';
@Entry()
@Component
struct MultiEnginePage implements EngineBindingsDelegate {
@State viewId1: string = "";
@State viewId2: string = "";
private context = getContext(this) as common.UIAbilityContext;
private engineBindings1: EngineBindings = new EngineBindings(this.context, this);
private engineBindings2: EngineBindings = new EngineBindings(this.context, this);
onNext() {
router.pushUrl({ "url": "pages/MainPage" });
}
aboutToAppear() {
Log.i("Multi->aboutToAppear", "MultiEnginePage");
this.viewId1 = this.engineBindings1.getFlutterViewId();
this.viewId2 = this.engineBindings2.getFlutterViewId();
// 顺序启动两个引擎
this.startEngine1();
this.startEngine2();
}
aboutToDisappear(): void {
this.engineBindings1.detach();
this.engineBindings2.detach();
}
private async startEngine1() {
try {
await this.engineBindings1.attach();
Log.i("Multi->startEngine1", "Engine 1 started successfully");
} catch (e) {
Log.e("Multi->startEngine1", "Failed to start engine 1: " + e);
}
}
private async startEngine2() {
try {
await this.engineBindings2.attach();
Log.i("Multi->startEngine2", "Engine 2 started successfully");
} catch (e) {
Log.e("Multi->startEngine2", "Failed to start engine 2: " + e);
}
}
build() {
Column() {
Text('多引擎示例页面').fontSize(24).margin(20)
Column() {
Text('Flutter引擎1').fontSize(18).margin(10)
FlutterPage({ viewId: this.viewId1, xComponentType: XComponentType.TEXTURE })
.backgroundColor(Color.LightGray)
.width('100%')
.height('45%')
}
Column() {
Text('Flutter引擎2').fontSize(18).margin(10)
FlutterPage({ viewId: this.viewId2, xComponentType: XComponentType.TEXTURE })
.backgroundColor(Color.LightGray)
.width('100%')
.height('45%')
}
}
}
}
六、注意事项
- 引擎生命周期管理:确保在页面销毁时正确detach和销毁引擎
- 资源消耗:虽然引擎之间共享资源,但仍需注意内存占用
- 性能优化:避免频繁创建和销毁引擎,可考虑使用引擎池
- 状态管理:不同引擎实例之间状态相互隔离,需要通过其他方式共享数据
- 插件兼容性:确保使用的Flutter插件兼容多引擎环境
- 错误处理:添加适当的错误处理机制,确保应用稳定性
七、总结
FlutterEngineGroup为OpenHarmony开发者提供了强大的多引擎管理能力,使开发者能够在单个应用中灵活地使用多个Flutter引擎实例。通过本文的介绍,开发者可以快速掌握FlutterEngineGroup的使用方法,包括环境搭建、依赖引入、引擎管理和双向通信等核心功能。
使用FlutterEngineGroup,开发者可以:
- 实现更灵活的混合开发架构
- 优化应用性能和资源利用
- 实现不同模块之间的隔离
- 充分利用Flutter的跨平台能力
- 构建更复杂、更高效的应用
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)