博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RN与原生交互(二)——数据传递
阅读量:5973 次
发布时间:2019-06-19

本文共 5595 字,大约阅读时间需要 18 分钟。

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

Demo地址:

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     */    @ReactMethod    public void getStringFromReactNative(String s) {        Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();    }复制代码

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

传递字典

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

/**     * RN向原生传递字典。这里原生端接收RN传过来的字典类型是ReadableMap     * @param map     */    @ReactMethod    public 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代码:

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

原生向RN回调数据

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

/**     * 原生通过回调的形式向RN端传递string     * @param callback     */    @ReactMethod    public void passStringBackToRN(Callback callback) {        callback.invoke("This is a string from Native");    }    /**     * 原生通过回调的形式向RN端传递字典。这里传出去的字典类型必须是WritableMap,java中的Map、HashMap是不能传递到RN的     * @param callback     */    @ReactMethod    public 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     */    @ReactMethod    public void passArrayBackToRN(Callback callback) {        WritableArray array = Arguments.createArray();        array.pushString("React Native");        array.pushString("Android");        array.pushString("iOS");        callback.invoke(array);    }    @ReactMethod    public 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:self                      selector:@selector(sendCustomEvent:)                          name:@"sendCustomEventNotification"                        object:nil];  }  return self;}/// 接收通知的方法,接收到通知后发送事件到RN端。RN端接收到事件后可以进行相应的逻辑处理或界面跳转- (void)sendCustomEvent:(NSNotification *)notification {  [self sendEventWithName:@"CustomEventName" body:@"这是发给RN的字符串"];}/// 重写方法,定义支持的事件集合- (NSArray
*)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();  }复制代码

转载地址:http://izdox.baihongyu.com/

你可能感兴趣的文章
cat_all.php
查看>>
Linux下Netfilter/IPTables防火墙案例分析
查看>>
Confluence 6 创建一个主题
查看>>
系统集成资质 - 临考必读
查看>>
软考培训 - 案例分析复习注意事项
查看>>
中文文档列表 - Oracle Database (文档 ID 1533057.1)
查看>>
解决Java项目部署疑难杂症
查看>>
最长的重复子序列 后缀数组 java实现
查看>>
ansile(2)模块之synchronize
查看>>
jquery如何让滚动条默认在最底部?
查看>>
电子商务系统的设计与实现(七):前后端系统UI设计的一些思考
查看>>
TensorFlow on Kubernetes的架构与实践
查看>>
JSP与Servlet之间的相互通信
查看>>
Java死锁实例
查看>>
Linux系统启动详解
查看>>
HashSet 源码分析
查看>>
shell dd
查看>>
mongodb 学习资料汇总
查看>>
Java读取属性配置文件
查看>>
2014-06-28 Web-Front的学习(2)-----CSS(层叠样式表)
查看>>