rn如何和原生进行通信,是单线程还是多线程,通信方式都有哪些

React Native(RN) 里,JS 和原生(Android / iOS)之间的通信 是一个核心机制。下面我按你关心的点,从线程模型 → 通信原理 → 通信方式 → 新旧架构对比,系统地讲一遍(偏工程视角)。


一、RN 是单线程还是多线程?

结论一句话

RN 是多线程架构,但 JS 执行本身是单线程的

RN 中的核心线程(经典架构)

1️⃣ JS Thread(单线程)
  • 执行 JS 代码(业务逻辑、状态更新)

  • JS 是 单线程运行

  • 如果 JS 线程阻塞:

    • UI 不更新

    • 动画卡顿

    • 手势延迟

2️⃣ UI Thread(主线程)
  • 原生 UI 渲染

  • 处理触摸事件

  • 不能阻塞

3️⃣ Native Modules Thread(或 Background Thread)
  • 执行原生模块逻辑

  • IO / 网络 / 计算

  • 可多线程并行

    ┌─────────────┐
    │ JS Thread │ (单线程)
    └─────────────┘

    Bridge

    ┌─────────────┐ ┌──────────────────┐
    │ UI Thread │ │ Native Modules │ (多线程)
    └─────────────┘ └──────────────────┘


二、RN 和原生通信的本质

核心思想

JS 与 Native 不能直接互相调用函数,只能通过"通信机制"

原因:

  • JS 运行在 JS 引擎(Hermes / JSC)

  • Native 运行在 JVM / Objective-C Runtime

  • 运行时不同,内存不共享(旧架构)


三、RN 与原生通信方式(重点)

1️⃣ Bridge 通信(经典 / 旧架构)

这是你必须掌握的基础

通信特点
  • 异步

  • 序列化(JSON)

  • 跨线程

  • 有性能瓶颈

通信流程(JS → Native)
复制代码
JS 调用
  ↓
参数序列化成 JSON
  ↓
Bridge 队列
  ↓
Native Module 方法
JS → Native
复制代码
import { NativeModules } from 'react-native';

NativeModules.DeviceModule.getDeviceInfo()
Native → JS(Callback / Promise)
复制代码
@ReactMethod
public void getDeviceInfo(Promise promise) {
  promise.resolve("Android");
}
适合场景
  • 普通业务

  • 调系统能力

  • 网络、文件、设备信息

缺点
  • 大量调用 → 卡顿

  • 高频通信(动画、手势)不合适


2️⃣ Callback / Promise(Bridge 的具体形式)

Callback
复制代码
NativeModules.TestModule.doSomething((res) => {});
  • 老方式

  • 回调地狱

  • 不推荐新项目使用

Promise(推荐)
复制代码
await NativeModules.TestModule.doSomething();

3️⃣ EventEmitter(Native → JS 事件)

适合 状态变化通知

JS 监听
复制代码
const emitter = new NativeEventEmitter(NativeModules.TestModule);

emitter.addListener('onChange', (data) => {
  console.log(data);
});
Native 发送
复制代码
reactContext
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
  .emit("onChange", data);
场景
  • 传感器

  • 网络状态

  • 原生回调事件


4️⃣ UI Component 通信(Props + Commands)

JS → Native UI
  • 通过 props

    <CustomView color="red" />
Native → JS
  • 通过事件回调

    <CustomView onChange={handleChange} />
特点
  • UI 级别通信

  • 性能优于普通 NativeModule


四、新架构通信方式(Fabric / TurboModules / JSI)

这是 RN 0.68+ / 0.71+ 的重点


5️⃣ JSI(JavaScript Interface)🔥

最大变化

JS 可以直接调用 C++ / Native 方法,无需 Bridge

特点
  • 同步调用

  • 无 JSON 序列化

  • 共享内存

  • 性能极高

调用示意
复制代码
JS ↔ C++ ↔ Native
使用场景
  • 高性能计算

  • 动画

  • 手势

  • 音视频

  • 游戏


6️⃣ TurboModules(JSI + Native Modules)

  • 新一代 NativeModule

  • 类型安全

  • 同步 / 异步

  • 无 Bridge 队列

    const device = TurboModuleRegistry.get('DeviceModule');
    device.getInfo(); // 同步 or 异步


7️⃣ Fabric(新 UI 架构)

  • UI 渲染走 C++

  • 减少 JS ↔ UI 通信

  • 与 JSI 深度结合


五、通信方式对比总结(非常重要)

通信方式 是否同步 性能 适用场景
Bridge ❌ 异步 一般 普通业务
Callback 一般 老代码
Promise 一般 推荐
EventEmitter 一般 事件通知
UI Props/Event 半同步 较好 UI 通信
JSI ⭐⭐⭐⭐ 高频 / 高性能
TurboModule ✅ / ❌ ⭐⭐⭐⭐ 新架构

六、面试 & 实战常考点(给你划重点)

面试常问

  • RN 为什么 JS 是单线程?

  • Bridge 为什么慢?

  • 如何避免 JS 卡顿?

  • JSI 为什么快?

  • TurboModules 和 NativeModules 区别?

实战建议

  • 普通功能 → NativeModules

  • 高频调用 → JSI

  • UI 通信 → Fabric / UIManager

  • 事件通知 → EventEmitter

相关推荐
好大哥呀3 小时前
Java Web的学习路径
java·前端·学习
HashTang3 小时前
【AI 编程实战】第 7 篇:登录流程设计 - 多场景、多步骤的优雅实现
前端·uni-app·ai编程
cos4 小时前
Fork 主题如何更新?基于 Ink 构建主题更新 CLI 工具
前端·javascript·git
小满zs4 小时前
Next.js第二十一章(环境变量)
前端·next.js
C***11504 小时前
Spring aop 五种通知类型
java·前端·spring
朝阳395 小时前
前端项目的【package-lock.json】详解
前端
摸鱼的春哥5 小时前
AI编排实战:用 n8n + DeepSeek + Groq 打造全自动视频洗稿流水线
前端·javascript·后端
nece0016 小时前
vue3杂记
前端·vue