Flutter for OpenHarmony

架构介绍

Flutter多引擎架构(FlutterEngineGroup)是Flutter框架在OpenHarmony平台上的核心特性之一,它允许开发者在单个应用中创建和管理多个Flutter引擎实例,实现以下核心优势:

  • 内存共享:多个引擎实例共享同一套Flutter运行时和资源,显著减少内存占用
  • 快速启动:新引擎实例可以复用现有引擎的JIT编译结果和缓存,提升启动速度
  • 隔离性:不同引擎实例之间保持状态隔离,避免相互干扰
  • 灵活集成:支持在OpenHarmony原生应用的不同页面或组件中嵌入独立的Flutter模块
  • 资源优化:通过统一管理引擎生命周期,优化系统资源的使用

Flutter多引擎架构特别适合以下场景:

  • 大型应用中需要隔离不同功能模块
  • 混合开发模式下需要在多个页面中嵌入Flutter组件
  • 对启动性能有较高要求的应用
  • 需要同时运行多个独立Flutter实例的应用

环境搭建

1. 安装Flutter SDK

# 克隆Flutter仓库
git clone https://atomgit.com/openharmony-sig/flutter_flutter.git flutter

# 设置环境变量
export PATH="$PATH:`pwd`/flutter/bin"

# 验证安装
flutter --version

2. 安装DevEco Studio

下载并安装OpenHarmony官方IDE DevEco Studio:

  • 下载地址:https://developer.harmonyos.com/cn/develop/deveco-studio
  • 安装要求:JDK 11+,Node.js 14.19.1+,HPM CLI 1.1.3+

项目创建与配置

1. 创建支持OpenHarmony的Flutter项目

flutter create --platforms ohos my_architecture_app
cd my_architecture_app

2. 以Git形式引入架构相关依赖

在项目的pubspec.yaml文件中,添加以下依赖配置:

dependencies:
  flutter:
    sdk: flutter

  # Flutter多引擎架构相关依赖
  flutter_engine_group:
    git:
      url: "https://atomgit.com/"
      path: "packages/flutter_engine_group/flutter_engine_group"

  # 其他必要依赖
  cupertino_icons: ^1.0.2

3. 安装依赖

flutter pub get

Flutter多引擎架构的使用

1. 配置EntryAbility

首先,需要修改OpenHarmony应用的EntryAbility类,使其继承自UIAbility并实现ExclusiveAppComponent接口:

// entry/src/main/ets/entryability/EntryAbility.ts
export default class EntryAbility extends UIAbility implements ExclusiveAppComponent<UIAbility>{
  detachFromFlutterEngine(): void {
    // 实现引擎分离逻辑
  }

  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);
  }
}

2. 封装引擎绑定类

创建EngineBindings类来封装FlutterEngine的创建、附加和分离操作:

// entry/src/main/ets/utils/EngineBindings.ts
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. 检查Flutter引擎加载器
    await engines.checkLoader(this.context, []);

    // 2. 创建并运行Flutter引擎实例
    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);

    // 注册插件
    GeneratedPluginRegistrant.registerWith(this.engine);

    // 初始化MethodChannel进行通信
    this.channel = new MethodChannel(this.engine, 'samples.flutter.dev/engine');
    this.channel.setMethodCallHandler((methodName, args, result) => {
      this.handleMethodCall(methodName, args, result);
    });
  }

  detach() {
    // 分离FlutterView与引擎
    this.flutterView.detachFromFlutterEngine();

    // 销毁引擎实例
    this.engine?.destroy();

    // 清理资源
    DataModel.instance.removeObserver(this);
    this.channel?.setMethodCallHandler(null);
  }

  private handleMethodCall(methodName: string, args: any, result: MethodResult) {
    // 处理来自Flutter的方法调用
    switch (methodName) {
      case 'getEngineId':
        result.success(this.engine?.hashCode.toString());
        break;
      default:
        result.notImplemented();
    }
  }

  // 实现DataModelObserver接口方法
  onDataModelChanged(data: any): void {
    // 处理数据模型变化
  }
}

3. 在页面中使用多引擎

创建一个页面组件,用于展示如何使用多引擎架构:

// entry/src/main/ets/pages/SingleFlutterPage.ts
@Entry()
@Component
struct SingleFlutterPage {
  @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() {
      // 显示FlutterView
      FlutterPage({ viewId: this.viewId, xComponentType: XComponentType.TEXTURE })
        .width('100%')
        .height('100%')

      // 原生按钮,用于导航到下一页
      Button("跳转到原生页面")
        .onClick(() => {
          this.onNext();
        })
        .margin(20)
        .backgroundColor('#007AFF')
        .textColor('#FFFFFF')
    }
  }
}

4. 在Dart端使用引擎组

在Flutter的Dart代码中,可以使用FlutterEngineGroup来创建和管理引擎实例:

// lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Engine Group Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter多引擎架构示例'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _engineId = 'Unknown';
  static const engineChannel = MethodChannel('samples.flutter.dev/engine');

  
  void initState() {
    super.initState();
    _getEngineId();
  }

  Future<void> _getEngineId() async {
    try {
      final String result = await engineChannel.invokeMethod('getEngineId');
      setState(() {
        _engineId = result;
      });
    } on PlatformException catch (e) {
      setState(() {
        _engineId = 'Failed to get engine id: ${e.message}';
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '当前引擎ID:',
            ),
            Text(
              _engineId,
              style: Theme.of(context).textTheme.headline6,
            ),
            const SizedBox(height: 20),
            Text(
              '这是Flutter多引擎架构示例',
              style: Theme.of(context).textTheme.bodyText1,
            ),
          ],
        ),
      ),
    );
  }
}

多引擎架构的最佳实践

1. 引擎生命周期管理

  • 仅在需要时创建引擎实例,避免不必要的资源消耗
  • 在页面或组件销毁时及时调用detach()方法释放引擎资源
  • 使用FlutterManager统一管理引擎实例的生命周期

2. 内存优化

  • 避免同时创建过多引擎实例,建议控制在5个以内
  • 合理设置引擎的初始路由和入口点,减少不必要的资源加载
  • 使用ImageCache等缓存机制优化图片资源的加载和共享

3. 通信优化

  • 对于频繁通信的场景,建议使用EventChannel而非MethodChannel
  • 合理设计通信协议,减少数据传输量
  • 避免在主线程中进行大量数据传输,影响UI性能

总结

Flutter多引擎架构(FlutterEngineGroup)为开发者提供了在OpenHarmony平台上构建复杂混合应用的强大能力。通过内存共享、快速启动和灵活集成等特性,它解决了传统单引擎架构在大型应用中面临的性能和隔离性问题。

使用Flutter多引擎架构,开发者可以:

  1. 在单个OpenHarmony应用中嵌入多个独立的Flutter模块
  2. 实现原生页面与Flutter页面的无缝切换
  3. 优化应用的内存使用和启动性能
  4. 提高代码的模块化和可维护性

Flutter多引擎架构的适配,进一步丰富了OpenHarmony平台的跨端开发能力,为开发者提供了更多样化的技术选择。随着Flutter生态的不断完善和OpenHarmony平台的快速发展,这种架构模式将在更多复杂应用场景中得到广泛应用。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐