深入实战:使用 Platform Channel 实现 Flutter 与 OpenHarmony 原生能力互通

深入实战:使用 Platform Channel 实现 Flutter 与 OpenHarmony 原生能力互通

作者:L、218
发布平台:CSDN
日期:2025年12月16日


引言

在上一篇文章《Flutter 与开源鸿蒙(OpenHarmony)的融合开发实践》中,我们成功将一个基础 Flutter 应用运行在 OpenHarmony 设备上。然而,真正的应用开发离不开对系统原生能力的调用------比如获取设备信息、访问传感器、使用蓝牙或分布式任务调度。

由于 OpenHarmony 并非 Android 或 iOS,Flutter 官方插件无法直接使用。此时,Platform Channel(平台通道) 成为我们打通 Dart 与 OpenHarmony 原生代码的关键桥梁。

本文将手把手教你:

  • 如何在 OpenHarmony 的 C++ 层实现 Platform Channel;
  • 如何从 Flutter(Dart)端发起方法调用;
  • 实战案例:获取 OpenHarmony 设备型号与系统版本。

一、Platform Channel 工作原理回顾

Flutter 的 Platform Channel 机制允许 Dart 代码与宿主平台(如 Android Java/Kotlin、iOS Objective-C/Swift)进行双向通信。在 OpenHarmony 上,由于其应用以 Native C++ + ArkTS 为主,我们需要在 C++ 层实现通道逻辑

整体架构如下:

复制代码
+------------------+       MethodChannel       +---------------------+
|   Flutter (Dart) | <---------------------> | OpenHarmony (C++)   |
+------------------+                         +---------------------+
        ↑                                             ↑
        |                                             |
        |                                             |
   UI / 业务逻辑                                调用 OHOS 系统 API

关键点 :OpenHarmony 的 Native 层可通过 OHOS::system::GetParameter() 等接口获取设备信息。


二、环境准备

确保你已完成以下前置条件:

  • DevEco Studio 4.1+
  • OpenHarmony SDK API 10(支持 Native C++ 开发)
  • Flutter SDK 3.19+
  • 已集成 flutter_openharmony 社区引擎(见上一篇)

三、实战:通过 Platform Channel 获取设备信息

步骤 1:Dart 端定义 MethodChannel

在 Flutter 项目中创建 platform_oh.dart

dart 复制代码
// lib/platform_oh.dart
import 'package:flutter/services.dart';

class OpenHarmonyPlatform {
  static const MethodChannel _channel =
      MethodChannel('com.example.flutter_oh/device_info');

  static Future<String> getDeviceModel() async {
    final String? result = await _channel.invokeMethod('getDeviceModel');
    return result ?? 'Unknown';
  }

  static Future<String> getSystemVersion() async {
    final String? result = await _channel.invokeMethod('getSystemVersion');
    return result ?? 'Unknown';
  }
}

📌 Channel 名为 com.example.flutter_oh/device_info,需与 C++ 端一致。


步骤 2:C++ 端实现 MethodCallHandler

在 OpenHarmony 项目的 entry/src/main/cpp/ 目录下创建 flutter_method_handler.cpp

cpp 复制代码
// flutter_method_handler.cpp
#include "flutter_method_handler.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "parameters.h" // OpenHarmony 系统参数头文件
#include <string>

// 辅助函数:将 std::string 转为 FlutterString
FlutterString CreateFlutterString(const std::string& str) {
    FlutterString f_str;
    f_str.struct_size = sizeof(FlutterString);
    f_str.value = str.c_str();
    return f_str;
}

void HandleMethodCall(FlutterMethodCall* method_call,
                      FlutterEngine engine) {
    const char* method = method_call->method_name;
    FlutterPlatformMessageResponseHandle* response_handle =
        method_call->response_handle;

    if (strcmp(method, "getDeviceModel") == 0) {
        // 调用 OpenHarmony API 获取设备型号
        char model[128] = {0};
        OHOS::system::GetParameter("ro.product.model", "Unknown", model, sizeof(model));
        std::string result(model);

        FlutterString f_result = CreateFlutterString(result);
        FlutterEngineSendPlatformMessageResponse(engine, response_handle,
            reinterpret_cast<const uint8_t*>(&f_result), sizeof(f_result));

    } else if (strcmp(method, "getSystemVersion") == 0) {
        char version[128] = {0};
        OHOS::system::GetParameter("ro.build.version.release", "Unknown", version, sizeof(version));
        std::string result(version);

        FlutterString f_result = CreateFlutterString(result);
        FlutterEngineSendPlatformMessageResponse(engine, response_handle,
            reinterpret_cast<const uint8_t*>(&f_result), sizeof(f_result));

    } else {
        // 方法未实现
        FlutterEngineSendPlatformMessageResponse(engine, response_handle, nullptr, 0);
    }
}

同时声明头文件 flutter_method_handler.h

cpp 复制代码
#ifndef FLUTTER_METHOD_HANDLER_H
#define FLUTTER_METHOD_HANDLER_H

#include "flutter/shell/platform/embedder/embedder.h"

void HandleMethodCall(FlutterMethodCall* method_call, FlutterEngine engine);

#endif

步骤 3:在 Flutter Engine 初始化时注册回调

修改 MainAbility.cpp,在引擎启动后设置 Platform Message 回调:

cpp 复制代码
// MainAbility.cpp
#include "flutter_method_handler.h"

static FlutterEngine g_flutter_engine = nullptr;

// Platform Message 回调函数
void OnPlatformMessage(const FlutterPlatformMessage* message, void* user_data) {
    if (strcmp(message->channel, "com.example.flutter_oh/device_info") == 0) {
        FlutterMethodCall* method_call = FlutterMethodCallCreate(message->message, message->message_size);
        HandleMethodCall(method_call, g_flutter_engine);
        FlutterMethodCallDestroy(method_call);
    }
}

void MainAbility::OnStart() {
    FlutterRendererConfig config = {};
    config.type = kOpenGL;
    // ... 配置 OpenGL 上下文

    FlutterProjectArgs args = {};
    args.assets_path = "/data/app/com.example.flutter_oh/assets";
    args.icu_data_path = "/system/etc/icu/icudt72l.dat";

    FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, this, &g_flutter_engine);

    // 注册 Platform Channel 回调
    FlutterEngineSetPlatformMessageCallback(g_flutter_engine, OnPlatformMessage);
}

⚠️ 注意:路径 /data/app/... 需根据实际 HAP 安装路径调整。


步骤 4:在 Flutter UI 中调用原生方法

修改 main.dart,展示设备信息:

dart 复制代码
// lib/main.dart(节选)
class _MyHomePageState extends State<MyHomePage> {
  String _model = 'Loading...';
  String _version = 'Loading...';

  @override
  void initState() {
    super.initState();
    _loadDeviceInfo();
  }

  Future<void> _loadDeviceInfo() async {
    final model = await OpenHarmonyPlatform.getDeviceModel();
    final version = await OpenHarmonyPlatform.getSystemVersion();
    setState(() {
      _model = model;
      _version = version;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('OH Native Bridge')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('设备型号: $_model', style: TextStyle(fontSize: 18)),
            Text('系统版本: $_version', style: TextStyle(fontSize: 18)),
          ],
        ),
      ),
    );
  }
}

四、运行效果展示

部署到 OpenHarmony 模拟器或真机后,应用将显示如下界面:

图1:Flutter 应用成功调用 OpenHarmony 原生 API 获取设备信息


五、扩展建议

  1. 封装通用插件 :可将上述逻辑封装为 openharmony_device_info 插件,供多个项目复用。
  2. 支持异步回调 :对于耗时操作(如蓝牙扫描),需在 C++ 层开启新线程,并通过 FlutterEngineSendPlatformMessage 主动推送结果。
  3. 错误处理:在 Dart 和 C++ 层均应加入 try-catch 或返回错误码,提升健壮性。

六、结语

通过 Platform Channel,我们成功打通了 Flutter 与 OpenHarmony 原生能力的壁垒。这不仅让现有 Flutter 应用能快速适配国产操作系统,也为未来构建高性能、跨设备的分布式应用打下基础。

🔜 下期预告:《Flutter + OpenHarmony 分布式开发:实现手机与智慧屏协同》


参考链接


欢迎点赞、收藏、评论!你希望 Flutter 在 OpenHarmony 上支持哪些原生能力?


原创内容,转载请注明出处。

相关推荐
Cat God 0075 小时前
Kafka单机搭建(二)
分布式·kafka·linq
爱吃大芒果5 小时前
Flutter 状态管理全家桶:Provider、Bloc、GetX 实战对比
开发语言·前端·javascript·flutter·华为·ecmascript
shjita5 小时前
hadoop运行jar包的相关配置参考!
大数据·hadoop·分布式
5 小时前
TIDB——TIKV——分布式事务与MVCC
数据库·分布式·tidb·分布式数据库·tikv·
5 小时前
TIDB——TIKV——RocksDB
数据库·分布式·tidb·分布式数据库·
Cat God 0075 小时前
Kafka单机搭建(一)
分布式·kafka
yumgpkpm5 小时前
Cloudera CDP 7.3下载地址、方式,开源适配 CMP 7.3(或类 CDP 的 CMP 7.13 平台,如华为鲲鹏 ARM 版)值得推荐
大数据·hive·hadoop·分布式·华为·开源·cloudera
Chasing__Dreams5 小时前
kafka--基础知识点--6.3--leader epoch机制
分布式·kafka
L、2185 小时前
Flutter 与 OpenHarmony 深度集成:构建分布式多端协同应用
分布式·flutter·wpf