React Native跨平台鸿蒙开发实战:JS 与 ArkTS Native的通信机制详解

人们眼中的天才之所以卓越非凡,并非天资超人一等而是付出了持续不断的努力。1 万小时的锤炼是任何人从平凡变成超凡的必要条件。------------ 马尔科姆·格拉德威尔

🌟 Hello,我是 Xxtaoaooo!

🌈 "代码是逻辑的诗篇,架构是思想的交响"

React Native 跨平台鸿蒙开发实战:JS 与 ArkTS/Native 的通信机制详解

在 React Native (RN) 开发中,JavaScript 运行在独立的线程中,而设备的原生能力(如相机、传感器、分布式软总线)则位于原生层。如何高效、安全地打通这两者,是跨平台开发的核心。在鸿蒙系统(HarmonyOS)中,我们通过 TurboModules 和 NativeModules 机制,实现 JS 与 ArkTS 的无缝双向通信。


一、鸿蒙原生能力调用的架构基础

鸿蒙系统提供了强大的分布式能力和丰富的硬件 API,要让 RN 应用享受到这些红利,必须通过 Bridge(桥接)或 JSI(JavaScript Interface)技术。

1.1 通信架构概览

RN 在鸿蒙上的通信机制主要分为两类:

  1. 异步通信 (Native Modules):基于 Bridge,适用于非高频、耗时操作(如文件读写、网络请求)。
  2. 同步通信 (TurboModules / JSI):基于 C++ 绑定,适用于高频、低延迟场景(如动画驱动、传感器数据)。

下图展示了 JS 侧调用鸿蒙原生 Sensor 能力的时序交互。
HarmonyOS SDK ArkTS/Native Layer TurboModule Bridge JS Thread (RN) HarmonyOS SDK ArkTS/Native Layer TurboModule Bridge JS Thread (RN) 传感器数据订阅流程 loop 传感器数据回调 1. subscribeSensor('accelerometer') 2. Invoke Native Method 3. sensor.on(SENSOR_TYPE_ID_ACCELEROMETER) 4. Data Changed Event 5. Send Event to JS 6. DeviceEventEmitter.emit()

图 1:JS 与 ArkTS 传感器数据交互时序图


二、实现 JS 调用 ArkTS 模块

让我们通过一个具体案例------调用鸿蒙系统的弹窗(Toast)能力,来演示如何编写一个自定义的 Native Module。

2.1 ArkTS 侧实现

首先,在鸿蒙工程的 entry/src/main/ets 目录下创建一个 Native Module。我们需要继承 RNModule 并实现相关接口。

typescript 复制代码
// HarmonyToastModule.ts
import { RNModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts'
import promptAction from '@ohos.promptAction'

export class HarmonyToastModule extends RNModule {
  constructor(ctx: TurboModuleContext) {
    super(ctx)
  }

  // 定义模块名称,JS 端将通过此名称调用
  getName() {
    return 'HarmonyToast'
  }

  // 暴露给 JS 的方法
  show(message: string, duration: number) {
    promptAction.showToast({
      message: message,
      duration: duration,
    })
  }
}

核心点评

ArkTS 代码直接调用了 @ohos.promptAction,这是鸿蒙原生提供的轻量级提示接口。通过继承 RNModule,我们将这个能力包装成了 RN 可识别的模块。

2.2 JS 侧封装

在 React Native 项目中,我们需要创建一个对应的 TS 接口文件,以便在业务代码中获得类型提示。

typescript 复制代码
// HarmonyToast.ts
import { TurboModule, TurboModuleRegistry } from 'react-native'

export interface Spec extends TurboModule {
  show(message: string, duration: number): void
}

// 获取 Native 模块,如果获取不到则返回 null
export default TurboModuleRegistry.get<Spec>('HarmonyToast')

三、实现 ArkTS 主动发送事件到 JS

除了 JS 主动调用,原生层也经常需要主动向 JS 发送消息,例如系统电量变化、分布式设备连接状态变更等。

3.1 ArkTS 发送事件

使用 RNInstance 提供的 emitDeviceEvent 方法。

typescript 复制代码
// 在某个 ArkTS 服务或组件中
this.ctx.rnInstance.emitDeviceEvent('onDeviceConnected', {
  deviceId: 'device_123',
  deviceType: 'tablet',
})

3.2 JS 监听事件

在 RN 组件中,使用 DeviceEventEmitter 进行监听。

javascript 复制代码
import { DeviceEventEmitter, useEffect } from 'react-native'

function DeviceMonitor() {
  useEffect(() => {
    const subscription = DeviceEventEmitter.addListener(
      'onDeviceConnected',
      (event) => {
        console.log('新设备连接:', event.deviceId)
      }
    )

    return () => {
      subscription.remove() // 记得清理监听
    }
  }, [])

  return null
}

四、安全性与权限处理建议

在调用原生能力时,权限管理是不可忽视的一环。

  1. 最小权限原则 :仅申请业务必需的权限(如 ohos.permission.CAMERA)。
  2. 动态申请:对于敏感权限,必须在运行时向用户请求授权。

4.1 权限申请流程

已授权
未授权


JS 发起调用
检查权限
执行原生逻辑
调用 requestPermissionsFromUser
用户同意?
返回权限拒绝错误

图 2:鸿蒙应用运行时权限申请流程

在 ArkTS 中,使用 abilityAccessCtrl 来管理权限:

typescript 复制代码
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'

// 检查并申请权限
async function requestCameraPermission(context: any) {
  const atManager = abilityAccessCtrl.createAtManager()
  const result = await atManager.requestPermissionsFromUser(context, [
    'ohos.permission.CAMERA',
  ])
  return result.authResults[0] === 0
}

🌟 嗨,我是 Xxtaoaooo!

⚙️ 【点赞】让更多同行看见深度干货

🚀 【关注】持续获取行业前沿技术与经验

🧩 【评论】分享你的实战经验或技术困惑

作为一名技术实践者,我始终相信:

每一次技术探讨都是认知升级的契机,期待在评论区与你碰撞灵感火花 🔥

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

相关推荐
kyriewen9 分钟前
面试官问你:“AI 能写 80% 的代码了,公司为什么还需要你?”
前端·javascript·面试
Goodbye3 小时前
从 Token 到 Embedding:LLM 核心基础深度解析
javascript·人工智能
用户938515635073 小时前
工具调用背后:LLM 如何突破“缸中大脑”,操控真实世界?
javascript·人工智能
Goodbye3 小时前
从函数到智能:LLM Tool Use 深度解析
javascript·人工智能
半个落月3 小时前
大模型到底是怎么“调用工具”的?从一个 Node.js Demo 看懂 Tool Use
javascript·人工智能
烬羽3 小时前
中英文 token 数量差一倍?两段 JS 代码搞懂 LLM 底层是怎么"读"文字的
javascript·程序员·架构
山河木马4 小时前
矩阵专题1-怎么创建模型矩阵(uModelMatrix)
javascript·webgl·计算机图形学
花椒技术4 小时前
HJPusher / HJPlayer SDK 实践:我们为什么把直播推播链路拆成一套可复用能力
设计模式·harmonyos·直播
前端开发爱好者8 小时前
支持 110 种文件预览!兼容 Vue、React、Svelte!
前端·javascript·vue.js
大家的林语冰10 小时前
👍 尤大重学 Webpack,Vite 8.1 再进化,打包模式复活!
前端·javascript·vite