RN 的EventEmitter 双向通信

React Native 的 EventEmitter 双向通信 ,本质是 JS 和 Native 之间通过事件机制互相通知

它和普通 Native Module 方法调用不同:

  • Native Module:JS 主动调用 Native
  • EventEmitter:Native 和 JS 都可以主动发送事件

通信模型:

yaml 复制代码
        JS
        |
        | emit / addListener
        |
 React Native Bridge
        |
        |
      Native

一、JS → Native(主动调用)

这个不是 EventEmitter 最典型场景,一般用 Native Module。

例如:

JS:

ini 复制代码
NativeModules.DeviceModule.start();

Native:

typescript 复制代码
@ReactMethod
public void start(){
    //执行原生逻辑
}

流程:

arduino 复制代码
JS
 |
Bridge
 |
Native Module
 |
Java/Kotlin

二、Native → JS(EventEmitter)

这是 EventEmitter 最常见用途。

例如:

Android 检测到:

  • 蓝牙状态变化
  • GPS变化
  • 推送消息
  • 传感器数据

Native:

csharp 复制代码
sendEvent(
    "onLocationChanged",
    params
);

JS监听:

ini 复制代码
DeviceEventEmitter.addListener(
    "onLocationChanged",
    data=>{
        console.log(data);
    }
);

流程:

arduino 复制代码
Android
 |
emit事件
 |
Bridge
 |
JS Listener

三、Android实现 EventEmitter

1. Native Module继承

java 复制代码
public class DeviceModule 
extends ReactContextBaseJavaModule {

    private ReactApplicationContext context;


    public DeviceModule(
        ReactApplicationContext context
    ){
        super(context);
        this.context=context;
    }


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

}

2. 发送事件

csharp 复制代码
private void sendEvent(
    String eventName,
    WritableMap params
){

    context
    .getJSModule(
        DeviceEventManagerModule.RCTDeviceEventEmitter.class
    )
    .emit(
        eventName,
        params
    );
}

这里:

复制代码
RCTDeviceEventEmitter

就是 RN 的事件桥。


3. 调用

比如:

kotlin 复制代码
WritableMap data =
Arguments.createMap();

data.putString(
 "message",
 "hello JS"
);


sendEvent(
 "DeviceEvent",
 data
);

四、JS监听

RN 新版本推荐:

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


const {
 DeviceModule
}=NativeModules;


const emitter =
new NativeEventEmitter(DeviceModule);



const subscription =
emitter.addListener(
 "DeviceEvent",
 data=>{
    console.log(data);
 }
);

取消监听:

csharp 复制代码
subscription.remove();

否则容易:

复制代码
Memory Leak

五、JS → Native事件

如果 JS 想发事件给 Native:

例如:

JS:

php 复制代码
DeviceEventEmitter.emit(
 "Login",
 {
  user:"Tom"
 }
);

但是:

Native 默认不能直接监听 JS EventEmitter。

通常做法:

JS调用Native Module

css 复制代码
NativeModules.UserModule.login(
{
 user:"Tom"
}
);

Native:

typescript 复制代码
@ReactMethod
public void login(
ReadableMap data
){

}

也就是说:

sql 复制代码
JS ---> Native

推荐:
Native Module

不是 EventEmitter

六、完整双向模型

markdown 复制代码
                 JS

          NativeEventEmitter
                 ↑
                 |
        Native ---> JS
        emit事件


                 ↓

          Native Module
                 ↑

        JS ---> Native
        method调用

                 Native

七、实际项目例子:扫码

JS启动扫码

ini 复制代码
Scanner.start();

Native:

scss 复制代码
startCamera();

扫码成功:

css 复制代码
emit(
 "ScanResult",
 {
   code:"123456"
 }
);

JS:

javascript 复制代码
scannerEmitter.addListener(
"ScanResult",
(result)=>{
 console.log(result.code);
});

八、RN 新架构(TurboModule)

旧架构:

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

新架构:

复制代码
JS
 |
JSI
 |
TurboModule
 |
Native

事件通常使用:

  • TurboModule
  • EventEmitter interface
  • Codegen

例如:

TypeScript:

typescript 复制代码
export interface Spec
extends TurboModule {

 readonly onChange:
 EventEmitter<string>;

}

Codegen 自动生成绑定。


总结

方向 推荐方式
JS调用Native Native Module
Native通知JS NativeEventEmitter
持续数据流 EventEmitter
一次请求返回 Promise/Callback
新架构 TurboModule + EventEmitter

实际开发中:

  • 蓝牙状态
  • 推送
  • GPS
  • NFC
  • 扫码
  • 原生播放器状态

基本都是:

markdown 复制代码
JS调用Native启动
        ↓
Native持续emit事件
        ↓
JS监听更新UI

这就是 RN EventEmitter 最典型的双向通信模式。

相关推荐
布鲁飞丝2 小时前
从零实现富文本编辑器#-浏览器选区与编辑器选区模型同步
java·前端·编辑器
写不来代码的草莓熊2 小时前
Cesium 地图交互绘制圆形、多边形
前端·javascript·地图
weixin_427771612 小时前
前端版本检测
前端
禅思院2 小时前
流式 Markdown 渲染完全指南【引子】
前端·架构·前端框架
JackSparrow4143 小时前
前端安全之JS混淆+请求加密+请求签名以提升爬虫难度
前端·javascript·后端·爬虫·python·安全
IMPYLH3 小时前
HTML 的 <em> 元素
java·前端·html
看昭奚恤哭3 小时前
基于 RuoYi-Vue-Pro 定制了一个后台管理系统 magic-admin , 开源出来!
前端·vue.js·开源
名为沙丁鱼的猫7295 小时前
【审计日志组件实践复盘】前端工程化 + 后端DDD架构(AOP切面拦截日志) + MBG
前端·架构
xqqxqxxq5 小时前
AI智能旅游规划系统 - 前端技术笔记
前端·笔记·旅游