RN原生交互 & 桥接

你提到"RN 原生交互 & 桥接 ",我理解你可能是在问 React Native(RN)如何和原生 Android/iOS 交互,以及 Bridge(桥接机制)怎么工作。下面从原理到实践梳理。


1. RN 和原生的关系

React Native 本质上是:

JavaScript/TypeScript 写业务逻辑 + 原生组件负责真正渲染和系统能力。

结构大致:

复制代码
            JS 层
 React Components
        |
        |  Bridge / JSI
        |
 Native 层
 Android(Java/Kotlin)
 iOS(Objective-C/Swift)
        |
 系统能力
 Camera / GPS / Bluetooth / UI

RN 需要原生能力时,就通过桥接调用:

例如:

  • • JS 调摄像头
  • • JS 调支付 SDK
  • • JS 调蓝牙
  • • Native 主动通知 JS

2. RN Bridge(旧架构)

传统 RN 架构:

复制代码
  JS Thread
    |
    | JSON Message
    |
Bridge
    |
    |
Native Modules

Bridge 主要负责:

    1. 方法调用
    1. 参数序列化
    1. 消息传递

例如:

JS:

复制代码
  NativeModules.DeviceInfo.getBattery()

Bridge:

复制代码
  {
  "module": "DeviceInfo",
  "method": "getBattery"
}

Android:

复制代码
  public class DeviceInfoModule extends ReactContextBaseJavaModule {

    @Override
    public String getName() {
        return "DeviceInfo";
    }


    @ReactMethod
    public void getBattery(Promise promise) {

        int level = 80;

        promise.resolve(level);
    }
}

返回:

复制代码
  80

JS:

复制代码
  const battery =
 await NativeModules.DeviceInfo.getBattery();

console.log(battery);

3. Native Module 原生模块桥接

Android

创建 Module:

复制代码
  public class ToastModule 
extends ReactContextBaseJavaModule {


    @Override
    public String getName() {
        return "ToastAndroid";
    }


    @ReactMethod
    public void show(String msg) {

        Toast.makeText(
          getReactApplicationContext(),
          msg,
          Toast.LENGTH_SHORT
        ).show();

    }
}

JS 调:

复制代码
  import {
 NativeModules
} from 'react-native';


NativeModules.ToastAndroid.show(
 "Hello Native"
);

iOS

Swift:

复制代码
  @objc(ToastModule)
class ToastModule:
 NSObject {


 @objc
 func show(
  _ message:String
 ){
    print(message)
 }


}

JS:

复制代码
  NativeModules.ToastModule.show(
 "hello ios"
)

4. Native 主动调用 JS

例如:

Native 收到:

  • • 推送消息
  • • 蓝牙数据
  • • 支付结果

需要通知 JS。

流程:

复制代码
  Native
 |
EventEmitter
 |
Bridge
 |
JS Listener

JS:

复制代码
  import {
 NativeEventEmitter,
 NativeModules
} from 'react-native';


const emitter =
new NativeEventEmitter(
 NativeModules.Device
);


emitter.addListener(
 "onMessage",
 data=>{
   console.log(data)
 }
);

Native:

Android:

复制代码
  sendEvent(
 "onMessage",
 params
);

JS 收到:

复制代码
  {
 message:"支付成功"
}

5. Native UI 组件桥接

除了调用方法,还可以让 RN 使用原生 View。

例如:

JS:

复制代码
  <MapView
 latitude={39.9}
 longitude={116.3}
/>

实际:

复制代码
  <MapView>
       |
       |
 Native UIView
       |
 MKMapView(Android MapView)

Android:

复制代码
  public class MapViewManager
extends SimpleViewManager<MapView>{


@Override
public String getName(){
 return "RCTMap";
}


@Override
protected MapView createViewInstance(
 ThemedReactContext context
){
 return new MapView(context);
}

}

6. TurboModule(新架构)

RN 新架构:

复制代码
  JS
 |
JSI
 |
C++
 |
Native

替代:

复制代码
  JS
 |
Bridge(JSON)
 |
Native

优势:

旧 Bridge TurboModule
JSON 序列化 直接调用
异步为主 支持同步
性能损耗高 性能更好
动态查找 静态类型

7. Fabric 渲染系统

旧:

复制代码
  JS
 |
Bridge
 |
UIManager
 |
Native View

新:

复制代码
  JS
 |
JSI
 |
Fabric Renderer
 |
Native UI

优势:

  • • 更快 UI 更新
  • • Concurrent React 支持
  • • 更少线程切换

8. JSI 是关键

JSI:

JavaScript Interface

它允许:

JS 直接调用 C++ 对象。

例如:

复制代码
  JS
 |
JSI
 |
C++
 |
C++ Module
 |
Native API

很多高性能库:

  • • Reanimated 3
  • • MMKV
  • • Skia

都是基于 JSI。


9. RN 和 Native 通信方式总结

场景 方案
JS 调 Native 方法 Native Module
Native 通知 JS EventEmitter
复杂数据流 JSI
原生 UI Native Component
高性能计算 TurboModule + JSI
动画 Worklet/JSI

10. 实际开发中怎么选?

普通功能

例如:

  • • 获取设备信息
  • • 调系统 API

用:

复制代码
  Native Module

高频调用

例如:

  • • 视频处理
  • • 图像处理
  • • 加密
  • • 大数据计算

用:

复制代码
  JSI
TurboModule

自定义控件

例如:

  • • 地图
  • • 视频播放器
  • • 图表

用:

复制代码
  Native Component
Fabric

11. 面试常问

Q1:RN Bridge 为什么慢?

因为:

复制代码
  JS对象
 ↓
JSON序列化
 ↓
线程切换
 ↓
Native执行
 ↓
JSON返回

大量通信会产生开销。


Q2:如何优化 Bridge?

  • • 减少 JS-Native 调用次数
  • • 批量传数据
  • • 使用 JSI
  • • 使用 TurboModule
  • • Native 处理高频逻辑

Q3:RN 新旧架构区别?

一句话:

老架构靠 Bridge 通信,新架构通过 JSI 让 JS 更直接地访问 Native 能力。

相关推荐
weixin_4316004428 分钟前
前端数据埋点(1):一次点击如何变成一条埋点
前端·js·数据埋点
IT_陈寒35 分钟前
Python线程池吞了异常还不告诉我,这谁顶得住啊
前端·人工智能·后端
计算机魔术师1 小时前
同样是AI辅助建造,为什么有的游戏三个月就烂尾了?
前端
用户921080262861 小时前
0. 做 Agent 产品,前端 AI 组件框架怎么选?
前端
拾年2752 小时前
React Hooks 进阶篇:useMemo / useCallback / useReducer / useImperativeHandle,用「算账 +
前端·javascript·react.js
Jackson__2 小时前
面试官:如何在老项目中使用新框架,并实现通信?
前端·javascript·面试
拾年2752 小时前
React Hooks 保姆级教程:把组件想象成失忆的打工人,4 个 Hook 带你原地起飞
前端·javascript·react.js
mmsx2 小时前
一个 Bug 修了 12 轮,根因只有一句话:AI 编程时代,日志才是唯一的真相
前端
默_笙2 小时前
😝 5 亿次循环卡死页面?我用 Web Worker 把它扔进后台线程,页面丝滑如初
前端·javascript