我的上篇文章中简单介绍了RN与原生基本的页面跳转,本篇主要总结RN和原生之间的数据传递方式,讲解RN和原生端之间如何互相传递数据。

Demo地址:DataTransfer

RN向原生传递数据

在上一篇文章中已经说明了怎样分别在iOS和Android端创建module类,怎样使用。这里不再赘述。RN向原生传递数据需要我们在module类中定义相关方法,方法参数即为RN传递过来的数据,原生端根据参数做相应处理。

传递字符串

iOS代码如下:

/// RN向原生传递字符串
RCT_EXPORT_METHOD(getStringFromReactNative:(NSString *)s) {NSString *msg = [NSString stringWithFormat:@"RN传递过来的字符串:%@", s];[self showAlert:msg];
}
复制代码

Android如下:

/*** RN向原生传递字符串* @param s*/@ReactMethodpublic void getStringFromReactNative(String s) {Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();}
复制代码

传递整数或其它数字类型与此类似。

传递字典

这个很关键,iOS端接收数据类型还是NSDictionary类型,但Android端接收参数可不是Map、HashMap之类的,而是ReadableMap,这里要划重点。

/*** RN向原生传递字典。这里原生端接收RN传过来的字典类型是ReadableMap* @param map*/@ReactMethodpublic void getDictionaryFromRN(ReadableMap map) {System.out.print(map);Toast.makeText(mContext, "已收到字典数据", Toast.LENGTH_SHORT).show();}
复制代码

iOS端核心代码:

/// RN向原生传递字典
RCT_EXPORT_METHOD(getDictionaryFromRN:(NSDictionary *)dict) {NSLog(@"RN传递过来的字典:%@", dict);NSString *name = [dict objectForKey:@"title"];[self showAlert:name];
}
复制代码

传递数组

iOS端接收参数类型可定义为NSArray,但Android端接收参数需要定义为ReadableArray,不能是java中的集合类型,如List、ArrayList是解析不到数据的。

Android代码:

@ReactMethodpublic void getArrayFromRN(ReadableArray array) {System.out.print(array);Toast.makeText(mContext, "已收到数组数据", Toast.LENGTH_SHORT).show();}
复制代码

原生向RN回调数据

以Android端为例,RN在调用以下方法时可以通过回调获取到原生端返回的数据。

/*** 原生通过回调的形式向RN端传递string* @param callback*/@ReactMethodpublic void passStringBackToRN(Callback callback) {callback.invoke("This is a string from Native");}/*** 原生通过回调的形式向RN端传递字典。这里传出去的字典类型必须是WritableMap,java中的Map、HashMap是不能传递到RN的* @param callback*/@ReactMethodpublic void passDictionaryBackToRN(Callback callback) {WritableMap map = Arguments.createMap();map.putString("name", "小明");map.putInt("age", 20);map.putString("gender", "male");map.putBoolean("isGraduated", true);callback.invoke(map);}/*** 原生通过回调的形式向RN端传递数组。这里传出去的字典类型必须是WritableArray* @param callback*/@ReactMethodpublic void passArrayBackToRN(Callback callback) {WritableArray array = Arguments.createArray();array.pushString("React Native");array.pushString("Android");array.pushString("iOS");callback.invoke(array);}@ReactMethodpublic void passPromiseBackToRN(String msg, Promise promise) {if (!msg.equals("")) {promise.resolve(true);} else {promise.reject("warning", "msg cannot be empty!");}}
复制代码

iOS端在回调数据时一般使用RCTResponseSenderBlock,任何数据类型都以block形式返回,示例如下:

/// 回传数组到RN端
RCT_EXPORT_METHOD(passArrayBackToRN:(RCTResponseSenderBlock)block) {if (block) {NSArray *items = @[@"React Native", @"Android", @"iOS"];block(@[items]);}
}
复制代码

iOS端以promise形式返回数据与Android不同,Android端定义了一个Promise类,iOS端还是通过block形式给出回调,使用RCTPromiseResolveBlock和RCTPromiseRejectBlock

/// 以promise形式回传数据到RN端
RCT_EXPORT_METHOD(passPromiseBackToRN:(NSString *)msg resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {if (![msg isEqualToString:@""]) {resolve(@(YES));} else {reject(@"warning", @"msg cannot be empty!", nil);}
}
复制代码

发送事件

Android端核心代码:

public void sendEvent(String eventName) {String dataToRN = "这是发给RN的字符串";mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, dataToRN);}
复制代码

sendEvent方法定义在module类中,在需要发送事件的地方调用sendEvent方法就可以将事件通知发给RN端。

RN端监听Android端发来的通知如下,这里假设事件名称为“CustomEventName”

componentWillMount(){ DeviceEventEmitter.addListener('CustomEventName', (e)=> {  console.log("接收到通知") ;});  }
复制代码

iOS端与Android不同,不使用DeviceEventEmitter做监听,而是用NativeEventEmitter。具体实现方案如下:

  1. 使Module类继承RCTEventEmitter,重写supportedEvents方法,在这个方法中声明支持的事件名称。
  2. 在Module类的init方法中使用NSNotificationCenter监听iOS端要发送事件的操作。
  3. 在NSNotification对应的通知方法中将事件发送给RN。

核心代码:

+ (id)allocWithZone:(struct _NSZone *)zone {static DataTransferModule *sharedInstance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{sharedInstance = [super allocWithZone:zone];});return sharedInstance;
}- (instancetype)init {self = [super init];if (self) {NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];[defaultCenter removeObserver:self];[defaultCenter addObserver:selfselector:@selector(sendCustomEvent:)name:@"sendCustomEventNotification"object:nil];}return self;
}/// 接收通知的方法,接收到通知后发送事件到RN端。RN端接收到事件后可以进行相应的逻辑处理或界面跳转
- (void)sendCustomEvent:(NSNotification *)notification {[self sendEventWithName:@"CustomEventName" body:@"这是发给RN的字符串"];
}/// 重写方法,定义支持的事件集合
- (NSArray<NSString *> *)supportedEvents {return @["CustomEventName"];
}
复制代码

比如在iOS端我有个页面A,点击页面中的一个button需要关掉当前页面并且发送数据给RN端,使RN端接收到数据后做跳转操作。那么在A中button的点击方法如下:

- (void)buttonClicked:(id)sender {[[NSNotificationCenter defaultCenter] postNotificationName:@"sendCustomEventNotification" object:nil];[self dismissViewControllerAnimated:YES completion:nil];
}
复制代码

Module类中接收到通知后就将这个要做的操作发送给RN了。RN端监听方法如下:

const DataTransferModule = NativeModules.DataTransferModule;componentDidMount() {let eventEmitter = new NativeEventEmitter(DataTransferModule);this.listener = eventEmitter.addListener("CustomEventName", (result) => {this.showAlert("获取到事件通知" + result);})}componentWillUnmount() {this.listener && this.listener.remove();}
复制代码

RN与原生交互(二)——数据传递相关推荐

  1. 《React-Native系列》2、RN与native交互与数据传递

    RN怎么与native交互的呢? 下面我们通过一个简单的Demo来实现:RN页面调起Native页面,Native页面选择电话本数据,将数据回传给RN展示. 首先是 Native侧 1.MainAct ...

  2. RN与原生交互(一)——基本页面跳转

    React Native(以下简称RN)开发app过程中大部分都可以在JS端完成,但是也有一些功能是需要原生端来完成的.这时RN与原生端就不可避免的需要进行交互,比如页面跳转和数据传递.本篇文章主要以 ...

  3. kafka传递文件_Kafka权威指南(二)数据传递/数据管道/数据镜像

    可靠的数据传递 可靠性保证 - kafka可以保证分区消息的顺序 - 只有当消息被写入分区的所有同步副本时,才被认为是已提交的 - 只要还有一个副本是活跃的,那么已经提交的消息就不会丢失 - 消费者只 ...

  4. 《React-Native系列》3、RN与native交互之Callback、Promise

    接着上一篇 React-Native系列 2.RN与native交互与数据传递 ,我们接下来研究另外的两种RN与Native交互的机制 一.Callback机制 首先Calllback是异步的,RN端 ...

  5. rn+与android+交互,React native 与Android原生交互方式(一)

    前言## 最近在做React Native开发的时候避免不了的需要原生模块和JS之间进行交互,其实RN和原生的通信大致分为两种情况:一种是Android主动向RN端发送事件和数据,另外一种是RN端被动 ...

  6. RN 与android原生交互

    缘由 有时候App需要访问平台api,但在RN中没有相应的模块,或者需要你复用一些原生代码,这就需要进一步开发RN原生模块.一般用React Native开发App时会用到一些原生模块,比如:在做社会 ...

  7. matlab 不同GUI之间的交互/不同GUI之间的数据传递

    matlab 不同GUI之间实现交互: 功能介绍: 当在主界面单击列表框中的选项时,次界面的输入框中自动显示主界面中的选项.按钮就不介绍啦,想想不是关键的东西,想要明白按钮的功能也十分简单,下面会把代 ...

  8. 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递

    通过第一天的学习之后,我们相信您已经对MVC有一些基本了解. 本节所讲的内容是在上节的基础之上,因此需要确保您是否掌握了上一节的内容.本章的目标是在今天学习结束时利用最佳实践解决方案创建一个小型的MV ...

  9. 用友二次开发_详解ERP系统与MES系统的数据传递——永康用友

    详解ERP系统与MES系统的数据传递--永康用友 摘要:本文将按照数据的传递方向"从ERP到MES"和"MES到ERP"分别介绍MES系统如何与其他软件连接,才 ...

最新文章

  1. 企业创新系列之:青苹之末
  2. 哈佛CASTER | 基于化学子结构表征预测药物相互作用
  3. 用这种方式,我每次都是朋友圈里第一个预见AI科技趋势的人
  4. 第6次全天课笔记-20180819
  5. 六边形溯源追踪算法编程思想与代码
  6. sql数据库JDBCTemplate和JPA使用
  7. 【C语言】C语言实现面向对象编程之继承
  8. 23种设计模式的有趣见解 .
  9. Oracle发布Java 8
  10. 解析Pinterest:兴趣乐园背后的大文章
  11. 语音识别系统功能_语音识别系统的应用
  12. [HDU3507]Print Article
  13. 蓝桥基础练习 杨辉三角形 JAVA
  14. 微信分享、极简微信分享、thinkphp微信分享、laravel微信分享、3分钟完成微信分享
  15. 让无线路由器告别电源束缚
  16. 短视频直播电商抖音项目孵化流程运营带货商业计划书方案范本
  17. 主流智能汽车电子架构
  18. web开发详解,学习web前端开发的网站
  19. halcon变量,图像与C++的一些转换(未完待续)
  20. 纪中 Day13Day14

热门文章

  1. 字符串查找strpos()函数用法
  2. 烂泥:nagios学习(四):pnp4nagios图形化绘制nagios数据
  3. 山寨高仿iPad难现山寨手机的辉煌
  4. Under the Hoods of Cache Fusion, GES, GRD and GCS
  5. 成功网络管理员必备“软件”素质
  6. 机器学习和算法学习网址
  7. 将本地代码上传github
  8. vue实践06-项目实践
  9. Nginx 配置https证书认证
  10. linux操作系统中的netstat命令查看端口状态的使用和window操作系统查看端口号