Native JSI实现RN与原生通信的示例代码 React
React,Native,JSI实现RN与原生通信的示例代码,博智网带你了解详细信息 。
目录
- 什么是JSI
- JSI有什么不同
- 在iOS中使用JSI
- iOS端配置
- RN端配置
- js调用带参数的原生方法
- 原生调用JS
- 原生调用带参数的JS方法
- 在原生端调用js的函数参数
- 总结
- 问题
- 参考资料
什么是JSI
React Native JSI (JavaScript Interface) 可以使 JavaScript 和 原生模块 更快、更简单的通信 。它也是React Native 新的架构体系中Fabric UI层 和 Turbo 模块的核心部分 。
JSI有什么不同
JSI 移除了原生代码和JavaScript代码之间的桥接(bridge),同时也省去了两端相互调用时大量的JSON序列化和反序列化操作 。JSI为原生和JS交互打开了新的大门 。下面是一些JSI的特点:
- JavaScript Interface 允许我们向JavaScript 运行时注册方法 。这些方法在js环境中可以通过 global对象获取并调用 。
- 我们完全可以使用C++或者在iOS里使用OC,在Android里使用Java实现这些注册方法 。
- 原先使用bridge 的方式实现的原生模块可以通过增加一层C++,快速转化为通过JSI实现 。
- 在iOS端实现非常简单,因为C++和OC 可以方便的实现混编 。
- 在Android中,我们需要通过JNI 做一些转化 。
- 这些方法可以是完全同步的,这意味着不必强制使用async 。await 。
在iOS中使用JSI
下面我们将一步一步的在iOS工程中使用JSI实现原生与JS的通信 。
创建一个新的React Native 项目
npx react-native init jsiDemo
iOS端配置
在iOS项目目录中创建C++文件,example.h、 example.cpp 。
example.h
#ifndef EXAMPLE_H#define EXAMPLE_Hnamespace facebook { namespace jsi {class Runtime; }}namespace example { void install(facebook::jsi::Runtime &jsiRuntime);}#endif /* EXAMPLE_H */example.m#include "example.h"#include <jsi/jsi.h>using namespace facebook::jsi;using namespace std;namespace example { void install(Runtime &jsiRuntime) {auto helloWorld = Function::createFromHostFunction(jsiRuntime,PropNameID::forAscii(jsiRuntime,"helloWorld"),0,[](Runtime &runtime,const Value &thisValue,const Value *arguments,size_t count) -> Value {string helloworld = "helloworld";return Value(runtime, String::createFromUtf8(runtime,helloworld));});jsiRuntime.global().setProperty(jsiRuntime, "helloWorld", move(helloWorld));}}
在上面的代码中,我们使用 createFromHostFunction 方法创建了一个方法,并通过setProperty 方法将其注册到js运行时 。
接下来,我们需要创建一个moudle, 在moudle中执行install 方法 。
我们创建OC 文件,SimpleJsi.h,SimpleJsi.mm
SimpleJsi.h
#import <React/RCTBridgeModule.h>@interface SimpleJsi : NSObject <RCTBridgeModule>@property (nonatomic, assign) BOOL setBridgeOnMainQueue;@end
SimpleJsi.mm
#import "SimpleJsi.h"#import <React/RCTBridge+Private.h>#import <React/RCTUtils.h>#import <jsi/jsi.h>#import "example.h"#import <sys/utsname.h>using namespace facebook::jsi;using namespace std;@implementation SimpleJsi@synthesize bridge = _bridge;@synthesize methodQueue = _methodQueue;RCT_EXPORT_MODULE()+ (BOOL)requiresMainQueueSetup {return YES;}- (void)setBridge:(RCTBridge *)bridge {_bridge = bridge;_setBridgeOnMainQueue = RCTIsMainQueue();[self installLibrary];}- (void)installLibrary {RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;if (!cxxBridge.runtime) {/*** This is a workaround to install library* as soon as runtime becomes available and is* not recommended. If you see random crashes in iOS* global.xxx not found etc. use this.*/dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC),dispatch_get_main_queue(), ^{/**When refreshing the app while debugging, the setBridgemethod is called too soon. The runtime is not ready yetquite often. We need to install library as soon as runtimebecomes available.*/[self installLibrary];});return;}example::install(*(facebook::jsi::Runtime *)cxxBridge.runtime);}@end
在 setBridge 方法中,我们调用了 example的 install 方法,完成方法的注册 。
RN端配置
修改App.js
import React from 'react';import type {Node} from 'react';import {Text, View, Button} from 'react-native';const App: () => Node = () => {const [result, setResult] = React.useState();const press = () => {setResult(global.helloWorld());};return (// eslint-disable-next-line react-native/no-inline-styles<View style={{backgroundColor: '#FFFFFF', height: '100%'}}><View style={{height: '10%'}} /><Button onPress={press} title="按钮" /><Text>{'调用helloword:' + result}</Text></View>);};export default App;
推荐阅读
- 实现脱贫的根本之策是什么扶贫
- 人的自我实现结果比过程重要
- 人生的理想可以从哪些方面去实现
- 祖国统一的意义
- 梦想实现的格言大全
- 荣耀盒子怎么通过电脑实现投屏
- 如何才能实现宽带一号多拨呢
- 建行的房贷卡为什么不能转账 还房贷的建设卡可以实现转账不
- 将为国家作出更大贡献 全红婵发文:终于实现儿时愿望
- 如何更好的实现其人生价值
