微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React native和原生之间的通信

RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之

间通信,主要有三种方法

1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript

2)使用Promise来实现。

3)原生模块向JavaScript发送事件。

关于使用回调,这是最简单的一种通信,这里可以看看官网的实现,今天要讲的是滴三种由原生模块向JavaScript发送事件。

(1)首先,你需要定义一个发送事件的方法。如下所示:

  1. /*原生模块可以在没有被调用的情况下往JavaScript发送事件通知
  2. 最简单的办法就是通过RCTdeviceeventemitter
  3. 这可以通过ReactContext来获得对应的引用,像这样:*/
  4. publicstaticvoidsendEvent(ReactContextreactContext,StringeventName,@NullableWritableMapparamss)
  5. {
  6. System.out.println("reactContext="+reactContext);
  7. reactContext
  8. .getJSModule(DeviceEventManagerModule.RCTdeviceeventemitter.class)
  9. .emit(eventName,paramss);
  10. }

其中方法名可以任意,但是参数不可改变。该方法可以放在你要复用的原生类中(即为原生类1)。

需要注意的是,由于版本问题,该函数中的参数reactContext有可能为null,此时会报NullPointException的错误。所以我们需要手动给reactContext赋值,见步骤2.

(2)我们在原生类1中,定义变量public static ReactContext MyContext;

然后在我们自定义的继承至ReactContextBaseJavaModule的类中给reactContext赋值。

如下所示:

此时,reactContext将不会是null。也就不会报错。

(3)在某个原生函数中向JavaScript发送事件。如下所示:


(4)在RN前端监听事件。首先导入DeviceEventEmitter,即import{ DeviceEventEmitter } from 'react-native'

然后使用componentWillMount建立监听。

代码如下:

    componentwillMount(){
  1. deviceeventemitter.addListener('EventName',function(){
  2. alert("sendsuccess");
  3. });
  4. }

注意:该监听必须放在class里边,和render、const对齐。

下边展示一个完整Demo,Demo功能如下:

(1)JavaScript端在监听一个事件。

(2)点击前端某行文字调用原生方法

(3)在原生方法中,延迟3s后向前端发送对应事件。

(4)前端接收到事件后,给出alert提示

代码如下:

ManiActivity.Java


ManiApplication.java


MyModule.java


MyPackage.java


Test.java


前端index.android.js代码如下:

copy
*SampleReactNativeApp
  • *https://github.com/facebook/react-native
  • *@flow
  • importReact,{Component}from'react';
  • import{
  • AppRegistry,
  • StyleSheet,
  • Text,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">DeviceEventEmitter,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">NativeModules,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">View
  • }from'react-native';
  • exportdefaultclassywqextendsComponent{
  • componentWillMount(){
  • //监听事件名为EventName的事件
  • });
  • constructor(props){
  • super(props);
  • this.state={
  • content:'这个是预定的接受信息',
  • render(){
  • return(
  • <Viewstyle={styles.container}>
  • <Textstyle={styles.welcome}
  • onPress={this.callNative.bind(this)}
  • >
  • 当你点我的时候会调用原生方法,原生方法延迟3s后会向前端发送事件。
  • 前端一直在监听该事件,如果收到,则给出alert提示!
  • </Text>
  • <Textstyle={styles.welcome}>
  • {this.state.content}
  • </View>
  • callNative()
  • NativeModules.MyModule.NativeMethod();
  • conststyles=StyleSheet.create({
  • container:{
  • flex:1,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">justifyContent:'center',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">alignItems:'center',108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">backgroundColor:'#F5FCFF',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">},108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">welcome:{
  • fontSize:20,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">textAlign:'center',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">margin:10,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">},248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">instructions:{
  • color:'#333333',108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">marginBottom:5,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">AppRegistry.registerComponent('ywq',()=>ywq);

  • 运行结果如下所示:

    点击之前:


    调用原生方法并且等待3s后:


    再说一个值得注意的地方,一般我们在接收到原生模块主动发来的事件时,都会进行一些操作,如更新UI,而不仅仅是弹出alert 。

    例如我们需要更新UI,代码如下:

    copy
    this.showState();
  • showState()
  • this.setState({content:'已经收到了原生模块发送来的事件'})
  • 很明显:当收到事件时,改变一个文本框的内容,即更新UI。

    运行结果如下,说明在此function中不能使用this,也就是我们并不能更新UI。


    那我们能做到在接收到事件后更新UI等后续操作吗?

    使用胖箭头函数(Fat arrow functions)

    修改UI代码如下:

      /**
    1. *SampleReactNativeApp
    2. *https://github.com/facebook/react-native
    3. *@flow
    4. */
    5. importReact,{Component}from'react';
    6. import{
    7. AppRegistry,
    8. StyleSheet,
    9. Text,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">deviceeventemitter,108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">NativeModules,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">View
    10. }from'react-native';
    11. exportdefaultclassywqextendsComponent{
    12. componentwillMount(){
    13. //监听事件名为EventName的事件
    14. deviceeventemitter.addListener('EventName',()=>{
    15. this.showState();
    16. alert("sendsuccess");
    17. });
    18. }
    19. constructor(props){
    20. super(props);
    21. this.state={
    22. content:'这个是预定的接受信息',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">}
    23. render(){
    24. return(
    25. <Viewstyle={styles.container}>
    26. <Textstyle={styles.welcome}
    27. onPress={this.callNative.bind(this)}
    28. >
    29. 当你点我的时候会调用原生方法,原生方法延迟3s后会向前端发送事件。
    30. 前端一直在监听该事件,如果收到,则给出alert提示!
    31. </Text>
    32. <Textstyle={styles.welcome}>
    33. {this.state.content}
    34. </View>
    35. );
    36. callNative()
    37. {
    38. NativeModules.MyModule.NativeMethod();
    39. showState()
    40. {
    41. this.setState({content:'已经收到了原生模块发送来的事件'})
    42. conststyles=StyleSheet.create({
    43. container:{
    44. flex:1,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">justifyContent:'center',108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">alignItems:'center',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">backgroundColor:'#F5FCFF',108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">},248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">welcome:{
    45. fontSize:20,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">textAlign:'center',108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">margin:10,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">},108); border-image: initial; list-style-type: decimal-leading-zero; list-style-image: initial; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">instructions:{
    46. color:'#333333',248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">marginBottom:5,248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; list-style-position: outside !important;">});
    47. AppRegistry.registerComponent('ywq',()=>ywq);
    运行之后,界面刷新了。

    原文地址:https://www.jb51.cc/react/305398.html

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

  • 相关推荐