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

发布于:2025-08-16 ⋅ 阅读:(24) ⋅ 点赞:(0)

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

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

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

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

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

  
  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

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管理部分:
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页面
@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引擎
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 命令:
flutter build har --release
//构建结果在 项目根目录/build/ohos/har/release
  • 性能优化
    频繁通信建议使用 EventChannel 替代 MethodChannel 以减少开销。

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

{
  "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文件

{
  "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,并调用原生功能。


网站公告

今日签到

点亮在社区的每一天
去签到