在 ArkUI-X 跨平台开发中,实现 ArkTS 与 Android/iOS 原生代码通信的核心机制是 Bridge(平台桥接),而非 Flutter 中的 MethodChannel。通过 Bridge,开发者可以在 ArkTS 侧调用原生平台能力(如相机、蓝牙等),或从原生侧向 ArkTS 侧发送消息

一、 核心通信模式

ArkUI-X 的 Bridge 提供了三种通信模式,以适应不同的业务场景:

  1. JSON 编解码模式:默认模式,支持基础数据类型、数组和结构化数据的传递,满足绝大多数常规业务场景。
  2. 二进制编解码模式:在 JSON 模式基础上增加了 Buffer 数据格式,专门用于传输图片、音视频等数据量较大的二进制场景。
  3. 线程并发模式:将耗时处理放到后台异步线程中,避免数据编解码阻塞主 UI 线程,确保 Bridge 调用者可连续发送数据。

二、 数据传递(sendMessage)

适用于原生平台与 ArkTS 侧之间进行双向的数据(消息)传递。

  • ArkTS 侧:使用 sendMessage 发送数据,通过 setMessageListener 接收原生平台发送的消息。
  • 原生侧(如 Android):同样使用 sendMessage 发送数据,通过 setMessageListener 监听 ArkTS 侧发来的消息。

通过定义统一接口与工厂模式,实现业务逻辑与底层平台代码的完全隔离。

// 1. 定义统一接口 (Commons层)
export interface CameraInterface {
  isCameraMuted(): boolean;
  createCameraInput(): void;
}

// 2. 鸿蒙原生实现
export class CameraLocal implements CameraInterface {
  isCameraMuted(): boolean {
    // 直接调用鸿蒙不支持跨平台的原生 API
    return false; 
  }
  createCameraInput(): void {
    // 鸿蒙原生相机逻辑
  }
}

// 3. ArkUI-X 跨平台实现 (Android/iOS)
export class CameraArkUIX implements CameraInterface {
  private bridge: Bridge;
  
  isCameraMuted(): boolean {
    // 通过 Bridge 调用 Android/iOS 原生能力
    return this.bridge.callMethodSync('isCameraMuted');
  }
  createCameraInput(): void {
    this.bridge.callMethod('createCameraInput');
  }
}

// 4. 统一入口工厂 (动态分发)
export class CameraImpl {
  static getInterface(): CameraInterface {
    // 根据当前运行环境动态返回对应实现类
    if (Environment.isHarmonyOS()) {
      return new CameraLocal();
    } else {
      return new CameraArkUIX();
    }
  }
}

三、 方法调用(callMethod)

适用于原生平台与 ArkTS 侧之间互相调用对方的方法。

  • ArkTS 调用原生:ArkTS 侧直接通过 callMethod 或 callMethodWithCallback 调用原生方法,原生侧供调用的方法无需提前注册(Android 侧需将访问修饰符定义为 public)。
  • 原生调用 ArkTS:ArkTS 侧需先通过 registerMethod 注册被调用的方法,原生侧再通过 callMethod 进行调用。同时,ArkTS 侧可通过 unregisterMethod 移除已注册的方法。

四、 代码实战:ArkTS 与 Android 互调

以下展示 ArkTS 与 Android 原生层进行方法调用的具体实现:

1. ArkTS 主动调用 Android 原生方法:

// ArkTS 侧封装参数并发起调用
let params: Record<string, Bridge.Parameter> = {
  "name": "xuan",
  "age": 18
};
let result = await this.bridge!.callMethod('getAppVersion', params);
// Android 侧对应的方法实现
public String getAppVersion(JSONObject params) {
    // 处理业务逻辑并返回结果
    return "1.0.0";
}

2. Android 主动调用 ArkTS 方法:

// Android 侧构建参数并发起调用
JSONObject params = new JSONObject();
try {
    params.put("name", "xuan");
    params.put("age", 18);
} catch (Exception e) {
    e.printStackTrace();
}
Object[] paramObject = {params};
MethodData methodData = new MethodData("getString", paramObject);
bridge.callMethod(methodData);
// ArkTS 侧接收并处理调用
getString(parameters?: Record<string, Bridge.Message>): Bridge.ResultValue {
  console.log(`----调用 getString:parameters-->${JSON.stringify(parameters)}`);
  return "ArkTS Response";
}

五、 分层解耦

为了实现“一码三平台”并减少架构修改,推荐采用分层架构设计

  • 上层业务(UI层):统一调用一套接口(如 CameraImpl.getInterface().isCameraMuted()),无需区分当前运行平台。
  • 公共能力层(Impl层):根据平台动态分发。在 HarmonyOS 下调用不支持跨平台的原生 API(CameraLocal);在 Android/iOS 下则通过 Bridge 调用原生能力(CameraArkUIX)。

六、 进阶架构:接口驱动与分层解耦

在大型跨平台项目中,强烈建议采用接口驱动(Interface-driven)的分层架构来封装 Bridge 调用,从而将业务逻辑与平台差异彻底隔离。

  1. 定义统一接口:在公共能力层(Commons)定义纯 ArkTS 接口(如 CameraInterface),声明如 isCameraMuted()createCameraInput() 等方法。
  2. 多端实现类
    • HarmonyOS 实现:创建 CameraLocal.ets,直接调用鸿蒙原生的不支持跨平台的 API。
    • ArkUI-X 实现:创建 CameraArkUIX.ets,内部通过 Bridge 调用 Android/iOS 的原生能力。
  3. 统一入口:提供 CameraImpl.getInterface() 工厂方法,根据当前运行环境动态返回对应的实现类。上层业务 UI 只需依赖接口,无需关心底层是哪个平台在执行。

七、 原生侧集成规范(以 Android 为例)

在使用 Bridge 实现 ArkTS 与原生代码互调时,原生侧的工程配置与代码规范至关重要:

  1. 方法访问权限:Android 侧供 ArkTS 调用的方法,必须将访问修饰符定义为 public,否则 Bridge 无法通过反射或动态代理访问。
  2. SDK 与混淆配置
    • 必须将 arkui_android_adapter.jar 放入 libs 目录,并确保动态库(如 libarkui_android.so)被正确打包进对应 ABI 目录。

    • 在 proguard-rules.pro 中必须添加防混淆规则,保留 ArkUI-X 核心适配类:

      -keep class ohos.stage.ability.adapter.**{*;}
      -keep class ohos.ace.adapter.**{*;}
      -keep class ohos.ace.plugin.**{*;}
  3. Android 入口类继承:Android 工程的 Application 和 Activity 必须继承 ArkUI-X 提供的基类 StageApplication 和 StageActivity,并在 onCreate 中正确设置实例名称(InstanceName)。

八、 通信性能优化与线程调度

高频或大数据量的跨端通信极易引发 UI 卡顿,需遵循以下优化策略:

  1. 启用线程并发模式:对于耗时的原生方法调用(如大文件读写、复杂图像处理),务必在原生平台侧创建桥接实例时指定为线程并发模式。这会将数据编解码与业务逻辑移至后台异步线程,避免阻塞主 UI 线程。
  2. 大数据采用二进制模式:当需要跨端传输图片、音视频等二进制流时,应切换为二进制编解码模式(支持 Buffer 数据格式),相比 JSON 模式能大幅降低序列化开销与内存峰值。
  3. 生命周期与监听注销:ArkTS 侧在页面销毁时,务必调用 unregisterMethod 移除已注册的方法监听,防止原生侧持有失效的 JS 上下文引用,从而引发内存泄漏。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐