Dart 调一个方法,参数怎么跑到 ArkTS 的?结果又怎么回来的?

文章封面

第一篇解决了"插件被发现"的问题。但插件找到了,怎么调用?

Dart 层写一个 invokeMethod('getDeviceInfo'),这行代码到底怎么跑到 HarmonyOS 的 ArkTS 代码?结果又怎么传回 Dart?

这就是 MethodChannel 要解决的问题。

一、先想清楚:MethodChannel 是什么

MethodChannel 就是 Dart 和原生之间的通信通道。Dart 发消息过去,原生处理完发回来。

方向做什么
Dart → ArkTS调用方法,传参数
ArkTS → Dart返回结果,传数据

不是函数调用,是消息传递。Dart 发一条消息,ArkTS 收到处理,再发一条回去。

二、一次调用的完整流程

完整流程:

  1. Dart 层调用 invokeMethod('getDeviceInfo', params)
  2. Flutter 引擎把方法名和参数序列化;
  3. 通过 Channel 传到 ArkTS;
  4. ArkTS 收到 MethodCall,处理;
  5. 处理完,调用 Result 返回结果;
  6. Flutter 引擎反序列化;
  7. 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 没 awaitResult 没调用,Dart 一直等
异常只打日志Result 没 error,Dart 不知道出错了
Result 调用两次第二次调用报错

记住:不管成功失败,都要调一次 Result。

五、几个容易踩的坑

第一个坑:Channel 名不一致。Dart 层和 ArkTS 层用的 Channel 名对不上。

第二个坑:方法名散落硬编码。到处都是字符串,改起来麻烦。

第三个坑:Promise 没有正确回 Result。Dart 那边一直等。

第四个坑:复杂对象无法序列化。自定义对象直接传,报错。

第五个坑:同一个 Result 回调两次。第二次调用报错。

第六个坑:异常只在 ArkTS 打日志导致 Dart 一直等待。Dart 不知道出错了。

测试效果图

这次做跨语言通信最大的体会是:MethodChannel 不是函数调用,是消息传递。Dart 和 ArkTS 是两个世界,中间靠消息通信。

真正做的时候,最容易忽略的不是怎么写代码,而是怎么管好这条通信链路。Channel 名、方法名、参数格式、结果返回,每一步都要对上。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐