《HarmonyOS 7 Flutter 三方插件鸿蒙化开发手记》02:MethodChannel 背后的 Dart 与 ArkTS 消息通路【鸿蒙心迹】
Dart 调一个方法,参数怎么跑到 ArkTS 的?结果又怎么回来的?

第一篇解决了"插件被发现"的问题。但插件找到了,怎么调用?
Dart 层写一个 invokeMethod('getDeviceInfo'),这行代码到底怎么跑到 HarmonyOS 的 ArkTS 代码?结果又怎么传回 Dart?
这就是 MethodChannel 要解决的问题。
一、先想清楚:MethodChannel 是什么
MethodChannel 就是 Dart 和原生之间的通信通道。Dart 发消息过去,原生处理完发回来。
| 方向 | 做什么 |
|---|---|
| Dart → ArkTS | 调用方法,传参数 |
| ArkTS → Dart | 返回结果,传数据 |
不是函数调用,是消息传递。Dart 发一条消息,ArkTS 收到处理,再发一条回去。
二、一次调用的完整流程
完整流程:
- Dart 层调用
invokeMethod('getDeviceInfo', params); - Flutter 引擎把方法名和参数序列化;
- 通过 Channel 传到 ArkTS;
- ArkTS 收到 MethodCall,处理;
- 处理完,调用 Result 返回结果;
- Flutter 引擎反序列化;
- Dart 层拿到结果。
这段代码解决什么问题: Dart 层调用。
文件: lib/my_plugin.dart
用途: Dart 接口
接入位置: 插件 Dart 层
class MyPlugin {
static const MethodChannel _channel = MethodChannel('my_plugin');
static Future<String> getPlatformVersion() async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
// ArkTS 层处理
class MyPlugin implements FlutterPlugin {
onMethodCall(call: MethodCall, result: MethodResult) {
if (call.method === 'getPlatformVersion') {
result.success('HarmonyOS 7.0.0');
} else {
result.notImplemented();
}
}
}

三、参数怎么传,结果怎么回
Dart 和 ArkTS 之间传的参数,不是随便传的。要能序列化。
| 类型 | 能不能传 |
|---|---|
| int, double, String | 能 |
| bool | 能 |
| List, Map | 能 |
| 自定义对象 | 不能,要转成 Map |
复杂对象不能直接传。要转成 Map 或者 JSON。
四、异步和 Promise 的矛盾
很多人写 ArkTS 层的时候,直接调一个异步 API,然后忘了调用 Result。Dart 那边就一直等着,永远不返回。
| 错误 | 问题 |
|---|---|
| 异步 API 没 await | Result 没调用,Dart 一直等 |
| 异常只打日志 | Result 没 error,Dart 不知道出错了 |
| Result 调用两次 | 第二次调用报错 |
记住:不管成功失败,都要调一次 Result。
五、几个容易踩的坑
第一个坑:Channel 名不一致。Dart 层和 ArkTS 层用的 Channel 名对不上。
第二个坑:方法名散落硬编码。到处都是字符串,改起来麻烦。
第三个坑:Promise 没有正确回 Result。Dart 那边一直等。
第四个坑:复杂对象无法序列化。自定义对象直接传,报错。
第五个坑:同一个 Result 回调两次。第二次调用报错。
第六个坑:异常只在 ArkTS 打日志导致 Dart 一直等待。Dart 不知道出错了。

这次做跨语言通信最大的体会是:MethodChannel 不是函数调用,是消息传递。Dart 和 ArkTS 是两个世界,中间靠消息通信。
真正做的时候,最容易忽略的不是怎么写代码,而是怎么管好这条通信链路。Channel 名、方法名、参数格式、结果返回,每一步都要对上。
更多推荐



所有评论(0)