React native与原生应用(二)--JS与原生应用间传递数据

参考react native中文网“原生模块(Android)” http://reactnative.cn/docs/0.48/native-modules-android.html#content,JS端与原生模块之间通信,主要有三种方法:
(1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript。
(2)使用Promise来实现。
(3)原生模块向JavaScript发送事件。

一、添加两个必要类
在使用这三种通信方法之前,在原生应用上需要实现三个类来与JS端进行交互:


Paste_Image.png
  1. new ReactPackages类
    在上一篇中,集成到现有原生应用中创建了一个类
ReactNativeInAndroidActivity extends ReactActivity implements DefaultHardwareBackBtnHand

在onCreate时,创建了一个ReactInstanceManager,并需要加入一个我们定义的一个ReactPackages

mReactInstanceManager = ReactInstanceManager.builder()
        .setApplication(getApplication())
        .setCurrentActivity(this)
        .setBundleAssetName("index.android.bundle")
        .setJSMainModuleName("currentDetail")
        .addPackage(new MainReactPackage())
        .addPackage(new AndroidNativePackage())//我们自己ReactPackages
        .setUseDeveloperSupport(true)
        .setInitialLifecycleState(LifecycleState.RESUMED)
        .setDefaultHardwareBackBtnHandler(this)
        .build();

new ReactPackages的实现可参考http://blog.csdn.net/qq_25827845/article/details/52963594,有一个简单的小例子来介绍用法。
在这个类中最关键的函数就是createNativeModules,
在该函数中我们需要new一个ReactContextBaseJavaModule类

public class AndroidNativePackage implements ReactPackage {
@Override
    public List<NativeModule>    createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new CurrentModule(reactContext));
        return modules;
    }
}
  1. new ReactContextBaseJavaModule类
public class CurrentModule extends ReactContextBaseJavaModule

在这个类中有两个重要的函数:
a.

public CurrentModule(ReactApplicationContext reactContext) {
    super(reactContext);
    //要把上下文传递给ReactActivity类即ReactNativeInAndroidActivity,否则ReactNativeInAndroidActivity获得不了上下文
    ReactNativeInAndroidActivity.mReactContext = reactContext;
}

b.

@Override
public String getName() {
    //返回的这个字符串在JavaScript端标记这个模块,在JS端可以通过NativeModules.CurrentDetailModuleg访问到这个模块
    return "CurrentDetailModule";
}

c. JS端通过上面的方法可以访问到CurrentModule这个类了,具体调用那个功能函数就需要使用下面这种方法

@ReactMethod //需要使用注解@ReactMethod。方法的返回类型必须为void
public void function() {
     处理逻辑
}

JS可以通过NativeModules.CurrentDetailModule.function来访问这个函数

二、RN前端与原生模块之间通信
1、回调函数Callback,它提供了一个函数来把返回值传回给JavaScript
原生应用:

@ReactMethod 
public void getLoginState(Callback callback)
 {
     try { 
           WritableMap map = Arguments.createMap(); 
           map.putString("isLogin", "0"); 
           callback.invoke(map);//把map传回给JS
      } catch (IllegalViewOperationException e) { 
           Logger.i("React-Native:getLoginState")); 
      } 
}

JS:

//可以访问到原生应用的CurrentDetailModule类
var bridge = NativeModules.CurrentDetailModule;
//访问CurrentDetailModule类中getLoginState函数,把原生传给JS的map赋值到properties
bridge.getLoginState((properties) => {
   //从properties中取得key对应的value的值进行判断
   if (properties["isLogin"] == '0') {
        bridge.gotoLogin();
 } else { 
// 
}
})
  1. 原生模块向JavaScript发送事件
    原生模块可以在没有被调用的情况下往JavaScript发送事件通知。最简单的办法就是通过RCTDeviceEventEmitter,这可以通过ReactContext来获得对应的引用
    原生应用:
@ReactMethod 
public void sendDataToJs() { 
    WritableMap params = Arguments.createMap(); 
    params.putString("SendData", "1234");//"SendData"是key值,通过它获得value值
    //"eventName"是JS端监听的事件的名称
    mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("eventName", params); 
}

JS:

componentWillMount() {//JS组件还没有开始渲染时
    this.callNative.bind(this); 
    //注册监听事件,监听事件名称为'eventName',监听处理函数
    onScanningResult
    DeviceEventEmitter.addListener('eventName', this.onScanningResult);
}

onScanningResult = (e) => { //e是从原生应用传过来的数据
    //通过e.SendData获取key为SendData的value值
    this.setState({ money: e.SendData, }); 
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容