一、FlutterEntry插件介绍

FlutterEntry是OpenHarmony平台上实现Flutter混合开发的核心组件,它提供了一种结构化的方式来管理Flutter引擎生命周期和插件注册,支持在原生应用中灵活嵌入和跳转Flutter界面。

核心功能

  • 生命周期管理:统一管理Flutter引擎的创建、运行和销毁
  • 插件注册:集中式注册Flutter插件,简化插件管理
  • 界面嵌入:支持在OpenHarmony页面中无缝嵌入Flutter视图
  • 导航集成:与OpenHarmony的Navigation组件深度集成,实现流畅的页面跳转
  • 状态管理:维护Flutter界面的状态,支持页面切换时的状态保存与恢复

二、环境准备

在开始使用FlutterEntry前,请确保已完成以下环境配置:

1. 基础开发环境

  • DevEco Studio:4.0及以上版本
  • JDK:17.0及以上版本
  • Flutter SDK:OpenHarmony适配版本
  • Node.js:16.0及以上版本

2. 环境变量配置

# 设置Flutter包管理镜像
export PUB_HOSTED_URL=https://mirrors.huaweicloud.com/repository/flutter/
export FLUTTER_STORAGE_BASE_URL=https://mirrors.huaweicloud.com/repository/flutter/

# 添加Flutter和OpenHarmony工具到PATH
export PATH=/path/to/flutter_flutter/bin:$PATH
export PATH=/path/to/ohos/tools:$PATH

3. 验证环境

# 验证Flutter版本
flutter --version

# 验证OpenHarmony环境
hdc version

三、EntryAbility配置与FlutterManager集成

FlutterEntry的使用需要先配置EntryAbility,与FlutterManager进行集成,管理Flutter引擎的生命周期。

1. 配置EntryAbility

EntryAbility.ets中实现FlutterManager的集成:

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import type Want from '@ohos.app.ability.Want';
import { FlutterManager, ExclusiveAppComponent } from '@ohos/flutter_ohos';

export default class EntryAbility extends UIAbility implements ExclusiveAppComponent<UIAbility> {
  // FlutterEntry接口方法实现
  detachFromFlutterEngine(): void {
    // 可在此处添加引擎分离逻辑
  }

  getAppComponent(): UIAbility {
    return this;
  }

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // 初始化时将UIAbility推入FlutterManager管理
    FlutterManager.getInstance().pushUIAbility(this);
  }

  onDestroy(): void | Promise<void> {
    // 销毁时将UIAbility从FlutterManager移除
    FlutterManager.getInstance().popUIAbility(this);
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 设置窗口为全屏模式
    windowStage.getMainWindowSync().setWindowLayoutFullScreen(true);
    // 将WindowStage推入FlutterManager管理
    FlutterManager.getInstance().pushWindowStage(this, windowStage);
    // 加载OpenHarmony页面
    windowStage.loadContent('pages/Index');
  }

  onWindowStageDestroy() {
    // 销毁时将WindowStage从FlutterManager移除
    FlutterManager.getInstance().popWindowStage(this);
  }
}

四、FlutterEntry继承与插件注册

通过继承FlutterEntry类,可以实现自定义的Flutter引擎配置和插件注册。

1. 创建自定义FlutterEntry

import { FlutterEntry, FlutterEngine } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '@ohos/flutter_ohos/src/main/ets/plugins/GeneratedPluginRegistrant';
import { BatteryPlugin } from '@ohos/battery_plugin'; // 示例插件

export default class MyFlutterEntry extends FlutterEntry {
  configureFlutterEngine(flutterEngine: FlutterEngine): void {
    // 调用父类方法完成基础配置
    super.configureFlutterEngine(flutterEngine);

    // 注册自动生成的插件
    GeneratedPluginRegistrant.registerWith(flutterEngine);

    // 手动注册自定义插件
    this.delegate?.addPlugin(new BatteryPlugin());
  }
}

五、FlutterEntry与FlutterView结合使用

FlutterEntry需要与FlutterView配合使用,才能在OpenHarmony页面中显示Flutter界面。

1. 基本使用方式

Index.ets中使用FlutterEntry和FlutterView:

import { FlutterEntry, FlutterView, FlutterPage } from '@ohos/flutter_ohos';
import { common } from '@kit.ArkUI';
import { Log } from '@kit.PerformanceAnalysisKit';

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;
  private flutterEntry: FlutterEntry | null = null;
  private flutterView?: FlutterView;

  aboutToAppear() {
    Log.d("Flutter", "Index aboutToAppear===");
    // 创建FlutterEntry实例
    this.flutterEntry = new MyFlutterEntry(getContext(this));
    // 初始化FlutterEntry
    this.flutterEntry.aboutToAppear();
    // 获取FlutterView实例
    this.flutterView = this.flutterEntry.getFlutterView();
  }

  aboutToDisappear() {
    Log.d("Flutter", "Index aboutToDisappear===");
    // 清理FlutterEntry资源
    this.flutterEntry?.aboutToDisappear();
  }

  // 页面显示时调用
  onPageShow() {
    Log.d("Flutter", "Index onPageShow===");
    this.flutterEntry?.onPageShow();
  }

  // 页面隐藏时调用
  onPageHide() {
    Log.d("Flutter", "Index onPageHide===");
    this.flutterEntry?.onPageHide();
  }

  build() {
    Stack() {
      // 使用FlutterPage组件显示Flutter界面
      FlutterPage({ viewId: this.flutterView?.getId() })
        .width('100%')
        .height('100%');
    }
  }

  // 处理返回按键
  onBackPress(): boolean {
    this.context.eventHub.emit('EVENT_BACK_PRESS');
    return true;
  }
}

六、Navigation配合FlutterEntry的使用方式

FlutterEntry可以与OpenHarmony的Navigation组件深度集成,实现页面间的流畅跳转。

1. 创建导航页面组件

import { FlutterEntry, FlutterView, FlutterPage } from '@ohos/flutter_ohos';
import { common } from '@kit.ArkUI';
import { NavDestination, NavDestinationContext, NavPathStack } from '@kit.NavigationKit';

@Builder
export function PageThreeBuilder() {
  PageThree()
}

@Component
export struct PageThree {
  private context = getContext(this) as common.UIAbilityContext;
  private flutterEntry: FlutterEntry | null = null;
  private flutterView?: FlutterView;
  private pathStack: NavPathStack = new NavPathStack();

  build() {
    NavDestination() {
      FlutterPage({ viewId: this.flutterView?.getId() })
        .width('100%')
        .height('100%');
    }
    .hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.init(context);
    })
    .onDisAppear(() => {
      this.flutterEntry?.aboutToDisappear();
    })
    .onShown(() => {
      this.flutterEntry?.onPageShow();
    })
    .onHidden(() => {
      this.flutterEntry?.onPageHide();
    })
    .onBackPressed(() => {
      this.context.eventHub.emit('EVENT_BACK_PRESS');
      return true;
    })
  }

  init(context: NavDestinationContext) {
    let pathStack = context.pathStack;
    this.pathStack = pathStack;
    // 获取页面参数
    let array = pathStack.getParamByName('pageThree') as Array<Record<string, Object>>;
    let params: Record<string, Object> = array.length > 0 ? array[0] : {};
    // 创建自定义FlutterEntry实例
    this.flutterEntry = new NavFlutterEntry(getContext(this), params, pathStack);
    // 初始化FlutterEntry
    this.flutterEntry.aboutToAppear();
    // 获取FlutterView实例
    this.flutterView = this.flutterEntry.getFlutterView();
  }
}

// 自定义导航FlutterEntry
class NavFlutterEntry extends FlutterEntry {
  private pathStack?: NavPathStack;

  constructor(context: common.Context, params: Record<string, Object> = {}, pathStack?: NavPathStack) {
    super(context, params);
    this.pathStack = pathStack;
  }

  // 处理系统导航返回
  popSystemNavigator(): boolean {
    if (this.pathStack) {
      this.pathStack.pop();
      return true;
    }
    return false;
  }
}

七、通过AtomGit引入依赖

在Flutter Module或OpenHarmony工程中,可以通过AtomGit引入FlutterEntry相关依赖。

1. 在Flutter Module中引入依赖

pubspec.yaml中添加AtomGit依赖:

dependencies:
  # 通过AtomGit引入flutter_ohos包
  flutter_ohos:
    git:
      url: "https://atomgit.com/flutter-openharmony/flutter_ohos"
      path: "packages/flutter_ohos/flutter_ohos"

  # 通过AtomGit引入其他Flutter插件
  battery_plugin:
    git:
      url: "https://atomgit.com/flutter-openharmony/plugins"
      path: "packages/battery_plugin/battery_plugin"

2. 更新依赖

执行以下命令更新依赖:

flutter pub get

3. 在OpenHarmony工程中引入依赖

oh-package.json5中添加HAR文件依赖:

{
  "dependencies": {
    "@ohos/flutter_ohos": "har/flutter.har",
    "@ohos/flutter_module": "har/flutter_module.har"
  }
}

八、完整代码示例

1. FlutterEntry完整实现

import { FlutterEntry, FlutterEngine, FlutterPlugin } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '@ohos/flutter_ohos/src/main/ets/plugins/GeneratedPluginRegistrant';

// 自定义插件示例
class MyCustomPlugin extends FlutterPlugin {
  // 插件实现
}

export default class CustomFlutterEntry extends FlutterEntry {
  configureFlutterEngine(flutterEngine: FlutterEngine): void {
    super.configureFlutterEngine(flutterEngine);

    // 注册所有插件
    GeneratedPluginRegistrant.registerWith(flutterEngine);

    // 注册自定义插件
    this.delegate?.addPlugin(new MyCustomPlugin());

    // 可以在此处添加其他引擎配置
    flutterEngine.getDartExecutor().executeDartEntrypoint(
      FlutterEngine.createDefaultDartEntrypoint()
    );
  }
}

2. 页面完整实现

import { FlutterEntry, FlutterView, FlutterPage } from '@ohos/flutter_ohos';
import { common } from '@kit.ArkUI';
import { Log } from '@kit.PerformanceAnalysisKit';
import CustomFlutterEntry from './CustomFlutterEntry';

@Entry
@Component
struct FlutterContainerPage {
  private context = getContext(this) as common.UIAbilityContext;
  private flutterEntry: FlutterEntry | null = null;
  private flutterView?: FlutterView;
  @State showNativeOverlay: boolean = false;

  aboutToAppear() {
    Log.d("Flutter", "FlutterContainerPage aboutToAppear");
    // 初始化FlutterEntry
    this.flutterEntry = new CustomFlutterEntry(getContext(this));
    this.flutterEntry.aboutToAppear();
    this.flutterView = this.flutterEntry.getFlutterView();

    // 监听Flutter消息
    this.setupMethodChannel();
  }

  aboutToDisappear() {
    Log.d("Flutter", "FlutterContainerPage aboutToDisappear");
    // 清理资源
    this.flutterEntry?.aboutToDisappear();
  }

  onPageShow() {
    Log.d("Flutter", "FlutterContainerPage onPageShow");
    this.flutterEntry?.onPageShow();
  }

  onPageHide() {
    Log.d("Flutter", "FlutterContainerPage onPageHide");
    this.flutterEntry?.onPageHide();
  }

  setupMethodChannel() {
    // 设置MethodChannel通信
    // 示例代码
  }

  build() {
    Stack() {
      // Flutter界面
      FlutterPage({ viewId: this.flutterView?.getId() })
        .width('100%')
        .height('100%');

      // 原生覆盖层(可显示/隐藏)
      if (this.showNativeOverlay) {
        Column() {
          Text('OpenHarmony Native Overlay')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .margin(20);

          Button('Hide Overlay')
            .onClick(() => {
              this.showNativeOverlay = false;
            });
        }
        .backgroundColor('#80ffffff')
        .padding(20)
        .margin(20);
      }

      // 显示原生覆盖层按钮
      Button('Show Native Overlay')
        .position({ x: 20, y: 80 })
        .onClick(() => {
          this.showNativeOverlay = true;
        });
    }
  }

  onBackPress(): boolean {
    Log.d("Flutter", "FlutterContainerPage onBackPress");
    // 处理返回按键
    this.context.eventHub.emit('EVENT_BACK_PRESS');
    return true;
  }
}

九、总结

FlutterEntry为OpenHarmony平台提供了强大的Flutter混合开发能力,通过以下步骤可以快速实现Flutter界面的嵌入和跳转:

  1. 环境准备:配置DevEco Studio、Flutter SDK和必要的环境变量
  2. EntryAbility配置:集成FlutterManager,管理Flutter引擎生命周期
  3. FlutterEntry继承:创建自定义FlutterEntry,注册所需插件
  4. 页面集成:在OpenHarmony页面中使用FlutterEntry和FlutterView
  5. 导航集成:与Navigation组件结合,实现流畅的页面跳转
  6. 依赖管理:通过AtomGit引入所需的Flutter包和插件

通过这种方式,开发者可以充分利用Flutter的跨平台能力和OpenHarmony的原生特性,构建高性能、高质量的跨平台应用。

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐