Flutter以模块化适配 HarmonyOS方案的实现步骤

Flutter 以模块化方案 适配 HarmonyOS 的实现方法

Flutter的SDK: https://gitcode.com/openharmony-tpc/flutter_flutter

分支Tag:3.27.5-ohos-0.1.0-beta

DevecoStudio:DevEco Studio 5.1.1 Release

HarmonyOS版本:API18

本文使用的Mac,环境配置步骤不再赘述,参考社区文档!!!

Flutter 应用可以通过与 HarmonyOS 原生代码交互来适配 HarmonyOS 平台。主要涉及 Flutter 端的插件开发和 HarmonyOS 端的原生能力实现。

Flutter 侧代码实现

在 Flutter 中,通过 MethodChannel 与 HarmonyOS 原生代码通信。以下是一个示例:

main.dart

dart 复制代码
void main() => runApp(GetMaterialApp(
      // home: const HomePage(),
      title: "Flutter侧",
      getPages: [
        GetPage(name: "/home", page: () => const HomePage()),
        GetPage(name: "/first", page: () => const FirstPage()), //空页面
      ],
    ));

home_page.dart

dart 复制代码
class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() {
    return _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {
  String deviceTypeName = "";
  String receiveData = "xxxxxx";

  @override
  void initState() {
    super.initState();
    Get.parameters.forEach((key, value) {
      if (key == "receiveData") {
        setState(() {
          receiveData = value!;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    deviceTypeName = Platform.operatingSystem;
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          '适配Android/iOS/HarmonyOS',
          style: TextStyle(fontSize: 20),
        ),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            deviceTypeName,
            style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
          ),
          const SizedBox(
            width: double.infinity,
            height: 20,
          ),
          Text('接收来自原生的数据:$receiveData'),
          const SizedBox(
            width: double.infinity,
            height: 20,
          ),
          GestureDetector(
            onTap: () {
              ToastUtil.showToastCenter("Send Native");
              NativeChannel.sendData();
            },
            child: Container(
              width: 120,
              height: 40,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: const Color(0xff08b326),
                  borderRadius: BorderRadius.circular(10)),
              child: const Text(
                "Send Native",
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          GestureDetector(
            onTap: () {
              ToastUtil.showToastCenter("Finish Page");
              NativeChannel.finishPage();
            },
            child: Container(
              width: 120,
              height: 40,
              margin: const EdgeInsets.only(top: 10),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: const Color(0xff08b326),
                  borderRadius: BorderRadius.circular(10)),
              child: const Text(
                "Finish Page",
                style: TextStyle(color: Colors.white),
              ),
            ),
          )
        ],
      ),
    );
  }
}

native_channel.dart

dart 复制代码
class NativeChannel {

  //创建通道
  static const _channel = MethodChannel('com.flutter/native_channel');

  ///调用原生方法,关闭原生页面
  static Future<void> finishPage() async {
    await _channel.invokeMethod('finishPage');
  }

  ///调用原生方法,发送flutter数据
  static Future<void> sendData() async {
    await _channel.invokeMethod('sendData', {'data': '我是FLutter传到原生客户端的数据'});
  }
}

HarmonyOS 侧代码实现

在 HarmonyOS 中,需要实现 Ability 来处理 Flutter 的调用。

  1. 创建项目默认创建 EntryAbility 类
    在 EntryAbility 类中初始化Flutter管理部分:
java 复制代码
export default class EntryAbility extends UIAbility {

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    FlutterManager.getInstance().pushUIAbility(this)
  }

  onDestroy(): void {
    FlutterManager.getInstance().popUIAbility(this)
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    FlutterManager.getInstance().pushWindowStage(this, windowStage);
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');

      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      // 1. 设置窗口全屏
      windowClass.setWindowLayoutFullScreen(true)
      // 2. 设置状态栏和导航条隐藏
      windowClass.setSpecificSystemBarEnabled('status', true)
      let sysBarProps: window.SystemBarProperties = {
        statusBarContentColor: '#000000'  //全局设置状态栏文字颜色
      };
      windowClass.setWindowSystemBarProperties(sysBarProps);

    });
  }

  onWindowStageDestroy(): void {
    FlutterManager.getInstance().popWindowStage(this);
  }

  onForeground(): void {
  }

  onBackground(): void {
  }
}
  1. 实现FlutterPage页面 负责承载FLutter模块的Harmony页面
java 复制代码
@Entry
@Component
struct FlutterViewPage {
  private flutterEntry?: FlutterEntry | null = null;
  private flutterView?: FlutterView;

  aboutToAppear() {
    //跳转至指定路由 ?后面为参数
    let params: Record<string, Object> = {
      "route": "/home?receiveData=HarmonyOS已经诞生5年了"
    }
    this.flutterEntry = new FlutterHomeAbility(getContext(this) as common.UIAbilityContext, params);
    this.flutterEntry.aboutToAppear();
    this.flutterView = this.flutterEntry.getFlutterView();
    this.flutterEntry.addPlugin(new HomePlugin(this.getUIContext()));
  }

  aboutToDisappear() {
    this.flutterEntry?.aboutToDisappear();
  }

  onPageShow() {
    this.flutterEntry?.onPageShow();
  }

  onPageHide() {
    this.flutterEntry?.onPageHide();
  }

  build() {
    RelativeContainer() {
      FlutterPage({ viewId: this.flutterView?.getId() })
        .width('100%')
        .height('100%')
    }
  }
}

class HomePlugin implements FlutterPlugin {
  private channel?: MethodChannel;	//交互通道
  private cxt?: UIContext

  constructor(context: UIContext) {
    this.cxt = context
  }

  getUniqueClassName(): string {
    return HomePlugin.name;
  }
  
  //交互过程
  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "com.flutter/native_channel");
    let context = this.cxt
    this.channel.setMethodCallHandler({
      onMethodCall(call: MethodCall, result: MethodResult) {
        switch (call.method) {
          case "finishPage":
            ToastUtil.showToast("页面关闭");
            context?.getRouter().back()
            break;
          case "sendData":
            ToastUtil.showToast("发送flutter数据:" + call.argument("data"));
            break;
          default:
            result.notImplemented();
            break;
        }
      }
    })
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {
    this.channel?.setMethodCallHandler(null)
  }
}
  1. 实现Flutter引擎
java 复制代码
export default class FlutterHomeAbility extends FlutterEntry {
  configureFlutterEngine(flutterEngine: FlutterEngine): void {
    super.configureFlutterEngine(flutterEngine);
    GeneratedPluginRegistrant.registerWith(flutterEngine);
  }
}

交互过程

  1. Flutter 调用 HarmonyOS 方法

    • Flutter 通过 MethodChannel 调用 finishPage 方法。
    • HarmonyOS 收到请求后处理信息。
  2. Flutter 向 HarmonyOS 传递参数

    • Flutter 调用 sendData 方法并传递 data 参数。
    • HarmonyOS 解析参数并显示 Toast。
  3. 通信流程

    • Flutter 发送方法名和参数到 HarmonyOS。
    • HarmonyOS 根据方法名执行对应逻辑并返回结果。

注意事项

  • 插件打包
    将 Flutter 代码打包为 Harmony可用的 har 插件,方便调用。
    Flutter打包 har 命令:
java 复制代码
flutter build har --release
//构建结果在 项目根目录/build/ohos/har/release
  • 性能优化

    频繁通信建议使用 EventChannel 替代 MethodChannel 以减少开销。

  • HarmonyOS侧导入har 1、项目根目录下oh-package.json5文件

java 复制代码
{
  "modelVersion": "5.1.1",
  "description": "Please describe the basic information.",
  "dependencies": {

  },
  "overrides": {//导入har包
    "@ohos/flutter_ohos": "file:../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/flutter_embedding_release.har",
    "flutter_native_arm64_v8a": "file:../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/arm64_v8a_release.har",
    "@ohos/flutter_module": "file:../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/flutter_module.har"
  },
  "devDependencies": {
    "@ohos/hypium": "1.0.21",
    "@ohos/hamock": "1.0.0"
  }
}

2、模块entry根目录下oh-package.json5文件

java 复制代码
{
  "name": "entry",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {//新增
    "@ohos/flutter_ohos": "file:../../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/flutter_embedding_release.har",
    "flutter_native_arm64_v8a": "file:../../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/arm64_v8a_release.har",
    "@ohos/flutter_module": "file:../../../FlutterProject/mobile_flutter_ohos/build/ohos/har/release/flutter_module.har"
  }
}

通过以上方法,Flutter 应用可以无缝适配 HarmonyOS,并调用原生功能。

相关推荐
梦想的颜色3 小时前
【编程实战】AI 时代 APP 开发全栈硬核指南:技术选型 + AI 架构 + 模型落地全维度决策
python·flutter·react native·react.js·ai·桌面应用·milvus
yuanlaile1 天前
2026年全新Flutter 跨平台开发全栈学习资料整理
flutter·getx·鸿蒙 next·flutter开发鸿蒙·flutter入门实战·flutter全栈
恋猫de小郭1 天前
Genkit Dart 1.0 发布,Flutter 原生的 AI Agent 终于完整了
android·前端·flutter
第10086个小白1 天前
flutter桌面端打包方式(Inno Setup Compiler)版本
前端·flutter
陆断枫2 天前
Flutter 3.47 动画引擎盘点:Impeller 全平台,和那些"新特性"
flutter
程序员老刘2 天前
Flet 1.0 思路很好,可惜来晚了
flutter·ai编程·客户端
m0_738185822 天前
Flutter 鸿蒙化实战:qr_code_scanner_plus 适配 OpenHarmony,二维码扫描
flutter·华为·harmonyos·鸿蒙
恋猫de小郭2 天前
Flutter + EmbeddingGemma 2,谷歌发布完全端侧的 AI Edge Foresight
android·前端·flutter
君赏3 天前
基于 FlutterPatch 快速接入 Flutter 热更新
flutter
律宏阔3 天前
Dart FFI 内存管理:用 using + Arena 替代嵌套 try-finally
前端·flutter