Flutter- OH 向鸿蒙发送数据实现指南
接口说明数据摘要接口,包含字符串长度和列表数量响应数据接口,符合 ArkTS 强类型要求。
·
Flutter-OH 向鸿蒙发送数据完整实现指南
一、实现原理
Flutter 与鸿蒙原生之间的数据通信通过 MethodChannel 实现双向数据传输:
- Flutter 端:通过 MethodChannel 发送数据(Map、List、基本类型等)
- 鸿蒙端:接收数据,处理后将结果返回给 Flutter
┌─────────────┐ MethodChannel ┌─────────────┐
│ Flutter │ ─────────────────────> │ 鸿蒙原生 │
│ 发送数据 │ sendDataToHarmony │ EntryAbility│
│ (Map类型) │ ─────────────────────> │ 处理数据 │
└─────────────┘ └──────┬──────┘
↑ │
└────────── 返回处理结果 <─────────────┘
二、完整代码实现
1. Flutter 端 - 平台通道封装
文件: lib/harmony_channel.dart
import 'package:flutter/services.dart';
/// 鸿蒙平台通道 - 用于 Flutter 与鸿蒙原生通信
class HarmonyChannel {
static const MethodChannel _channel =
MethodChannel('com.example.test1/harmony');
/// 向鸿蒙发送数据
/// [data] 要发送的数据,可以是 Map、List、String、int、double、bool 等
/// 返回鸿蒙端的处理结果
static Future<dynamic> sendDataToHarmony(dynamic data) async {
try {
final result = await _channel.invokeMethod('sendDataToHarmony', data);
print('数据发送成功,鸿蒙返回: $result');
return result;
} on PlatformException catch (e) {
print('向鸿蒙发送数据失败: ${e.message}');
rethrow;
}
}
}
代码解读:
| 代码段 | 说明 |
|---|---|
invokeMethod('sendDataToHarmony', data) |
调用鸿蒙端方法,并传递数据参数 |
dynamic data |
支持任意类型的数据:Map、List、String、int、double、bool 等 |
Future<dynamic> |
异步返回鸿蒙端的处理结果 |
PlatformException |
处理平台调用异常 |
数据类型支持:
- 基本类型:
String、int、double、bool - 集合类型:
List、Map - 嵌套结构:Map 中可以包含 List 或其他 Map
2. Flutter 端 - UI 界面
文件: lib/main.dart
import 'package:flutter/material.dart';
import 'harmony_channel.dart';
// ... 其他代码 ...
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 30),
// 发送数据到鸿蒙的按钮
ElevatedButton.icon(
onPressed: () async {
// 构造要发送的数据
final data = {
'title': '来自 Flutter 的数据',
'message': '你好,鸿蒙!',
'timestamp': DateTime.now().toIso8601String(),
'counter': _counter,
'items': ['item1', 'item2', 'item3'],
};
final result = await HarmonyChannel.sendDataToHarmony(data);
// 显示返回结果
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('鸿蒙返回: $result')),
);
}
},
icon: const Icon(Icons.send),
label: const Text('发送数据到鸿蒙'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
backgroundColor: Colors.green,
),
),
],
代码解读:
| 代码段 | 说明 |
|---|---|
final data = {...} |
构造要发送的数据 Map,包含多种类型的字段 |
DateTime.now().toIso8601String() |
生成 ISO 8601 格式的时间戳 |
HarmonyChannel.sendDataToHarmony(data) |
调用平台通道发送数据 |
ScaffoldMessenger.of(context).showSnackBar |
显示鸿蒙返回的结果 |
if (mounted) |
检查 Widget 是否仍在树中,避免内存泄漏 |
backgroundColor: Colors.green |
设置按钮为绿色 |
发送的数据结构:
{
'title': '来自 Flutter 的数据', // String
'message': '你好,鸿蒙!', // String
'timestamp': '2024-01-15T10:30:00.000Z', // String (ISO 8601)
'counter': 5, // int
'items': ['item1', 'item2', 'item3'] // List<String>
}
3. 鸿蒙端 - EntryAbility(接收数据处理)
文件: ohos/entry/src/main/ets/entryability/EntryAbility.ets
import {
FlutterAbility,
FlutterEngine,
MethodChannel,
Log,
MethodCall,
MethodResult,
MethodCallHandler,
BinaryMessenger
} from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
const TAG = 'EntryAbility';
const CHANNEL_NAME = 'com.example.test1/harmony';
// 定义数据摘要接口
interface DataSummary {
titleLength: number;
messageLength: number;
itemCount: number;
}
// 定义响应接口
interface ResponseData {
code: number;
message: string;
receivedAt: string;
dataSummary: DataSummary;
}
export default class EntryAbility extends FlutterAbility {
private methodChannel: MethodChannel | null = null;
configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
// 注册 MethodChannel 处理 Flutter 调用
let messenger: BinaryMessenger = flutterEngine.dartExecutor.getBinaryMessenger();
this.methodChannel = new MethodChannel(messenger, CHANNEL_NAME);
let methodCallHandler: MethodCallHandler = {
onMethodCall: (call: MethodCall, result: MethodResult) => {
Log.i(TAG, '收到 Flutter 调用: ' + call.method);
if (call.method === 'sendDataToHarmony') {
// 处理 Flutter 发送的数据
this.handleDataFromFlutter(call, result);
} else {
result.notImplemented();
}
}
};
this.methodChannel.setMethodCallHandler(methodCallHandler);
}
// 处理 Flutter 发送的数据
private handleDataFromFlutter(call: MethodCall, result: MethodResult): void {
Log.i(TAG, '收到 Flutter 发送的数据');
// 获取数据参数
let title: string = '';
let message: string = '';
let timestamp: string = '';
let counter: number = 0;
let items: Array<string> = [];
// 从 call 中获取参数(使用 hasArgument 检查后再获取)
if (call.hasArgument('title')) {
title = call.argument('title') as string;
}
if (call.hasArgument('message')) {
message = call.argument('message') as string;
}
if (call.hasArgument('timestamp')) {
timestamp = call.argument('timestamp') as string;
}
if (call.hasArgument('counter')) {
counter = call.argument('counter') as number;
}
if (call.hasArgument('items')) {
items = call.argument('items') as Array<string>;
}
// 打印接收到的数据
Log.i(TAG, '标题: ' + title);
Log.i(TAG, '消息: ' + message);
Log.i(TAG, '时间戳: ' + timestamp);
Log.i(TAG, '计数器: ' + counter);
Log.i(TAG, '列表项: ' + JSON.stringify(items));
// 构造返回结果 - 使用显式接口类型
let dataSummary: DataSummary = {
titleLength: title.length,
messageLength: message.length,
itemCount: items.length
};
let response: ResponseData = {
code: 200,
message: '数据接收成功',
receivedAt: new Date().toISOString(),
dataSummary: dataSummary
};
Log.i(TAG, '返回给 Flutter: ' + JSON.stringify(response));
// 返回成功结果给 Flutter
result.success(response);
}
}
代码解读:
3.1 接口定义
| 接口 | 说明 |
|---|---|
DataSummary |
数据摘要接口,包含字符串长度和列表数量 |
ResponseData |
响应数据接口,符合 ArkTS 强类型要求 |
3.2 数据接收处理
| 代码段 | 说明 |
|---|---|
call.hasArgument('key') |
检查参数是否存在 |
call.argument('key') |
获取指定 key 的参数值 |
as string / as number |
类型断言,将参数转换为具体类型 |
3.3 响应数据构造
// 构造返回结果
let response: ResponseData = {
code: 200,
message: '数据接收成功',
receivedAt: new Date().toISOString(),
dataSummary: {
titleLength: title.length,
messageLength: message.length,
itemCount: items.length
}
};
// 返回给 Flutter
result.success(response);
返回的数据结构:
{
"code": 200,
"message": "数据接收成功",
"receivedAt": "2024-01-15T10:30:01.123Z",
"dataSummary": {
"titleLength": 10,
"messageLength": 6,
"itemCount": 3
}
}
三、关键技术点
1. ArkTS 强类型要求
鸿蒙 ArkTS 是强类型语言,所有对象必须显式声明类型:
// ❌ 错误:未声明类型的对象字面量
let response = {
code: 200,
message: '成功'
};
// ✅ 正确:使用接口声明类型
interface ResponseData {
code: number;
message: string;
}
let response: ResponseData = {
code: 200,
message: '成功'
};
2. 数据类型映射
| Flutter 类型 | 鸿蒙 ArkTS 类型 |
|---|---|
String |
string |
int |
number |
double |
number |
bool |
boolean |
List |
Array<T> |
Map |
ESObject / 接口 |
3. 参数获取方式
// 方式1:直接获取(需要类型断言)
let title = call.argument('title') as string;
// 方式2:先检查再获取(推荐,更安全)
if (call.hasArgument('title')) {
title = call.argument('title') as string;
}
四、运行效果
-
Flutter 页面显示绿色按钮:“发送数据到鸿蒙”
-
点击按钮后:
- Flutter 构造数据 Map
- 通过 MethodChannel 发送到鸿蒙
- 鸿蒙接收并处理数据
- 鸿蒙返回处理结果
- Flutter 显示 SnackBar 展示返回结果
-
日志输出:
[EntryAbility] 收到 Flutter 发送的数据 [EntryAbility] 标题: 来自 Flutter 的数据 [EntryAbility] 消息: 你好,鸿蒙! [EntryAbility] 计数器: 5 [EntryAbility] 返回给 Flutter: {"code":200,...}

五、扩展建议
- 复杂数据类型:可以发送嵌套的 Map 和 List
- 大数据量:建议分批发送或使用文件传输
- 错误处理:添加更完善的异常处理机制
- 数据校验:在接收端添加数据合法性校验
更多推荐



所有评论(0)