React native和原生之间的通信
RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之
间通信,主要有三种方法:
1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript。
2)使用Promise来实现。
3)原生模块向JavaScript发送事件。
关于使用回调,这是最简单的一种通信,这里可以看看官网的实现,今天要讲的是滴三种由原生模块向JavaScript发送事件。
(1)首先,你需要定义一个发送事件的方法。如下所示:
- /*原生模块可以在没有被调用的情况下往JavaScript发送事件通知。
- 最简单的办法就是通过RCTDeviceEventEmitter,
- 这可以通过ReactContext来获得对应的引用,像这样:*/
- public static void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap paramss)
- {
- System.out.println("reactContext="+reactContext);
- reactContext
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
- .emit(eventName, paramss);
- }
其中方法名可以任意,但是参数不可改变。该方法可以放在你要复用的原生类中(即为原生类1)。
需要注意的是,由于版本问题,该函数中的参数reactContext有可能为null,此时会报NullPointException的错误。所以我们需要手动给reactContext赋值,见步骤2.
(2)我们在原生类1中,定义变量public static ReactContext MyContext;
然后在我们自定义的继承至ReactContextBaseJavaModule的类中给reactContext赋值。
如下所示:
- public class MyModule extends ReactContextBaseJavaModule {
- private BluetoothAdapter mBluetoothAdapter = null;
- public MyModule(ReactApplicationContext reactContext) {
- super(reactContext);
- 原生类1.MyContext=reactContext;
- }
- .......以下写被@ReactNative所标注的方法
- ............................
- ...................
- }
此时,reactContext将不会是null。也就不会报错。
(3)在某个原生函数中向JavaScript发送事件。如下所示:
- WritableMap event = Arguments.createMap();
- sendEvent(MyContext, "EventName",event);
(4)在RN前端监听事件。首先导入DeviceEventEmitter,即import{ DeviceEventEmitter } from 'react-native'
然后使用componentWillMount建立监听。
代码如下:
- componentWillMount(){
- DeviceEventEmitter.addListener('EventName', function() {
- alert("send success");
- });
- }
注意:该监听必须放在class里边,和render、const对齐。
);
前端index.android.js代码如下:
- /**
- * Sample React Native App
- * https://github.com/facebook/react-native
- * @flow
- */
- import React, { Component } from 'react';
- import {
- AppRegistry,
- StyleSheet,
- Text,
- DeviceEventEmitter,
- NativeModules,
- View
- } from 'react-native';
- export default class ywq extends Component {
- componentWillMount(){
- //监听事件名为EventName的事件
- DeviceEventEmitter.addListener('EventName', function() {
- alert("send success");
- });
- }
- constructor(props) {
- super(props);
- this.state = {
- content: '这个是预定的接受信息',
- }
- }
- render() {
- return (
- <View style={styles.container}>
- <Text style={styles.welcome}
- onPress={this.callNative.bind(this)}
- >
- 当你点我的时候会调用原生方法,原生方法延迟3s后会向前端发送事件。
- 前端一直在监听该事件,如果收到,则给出alert提示!
- </Text>
- <Text style={styles.welcome} >
- {this.state.content}
- </Text>
- </View>
- );
- }
- callNative()
- {
- NativeModules.MyModule.NativeMethod();
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- },
- instructions: {
- textAlign: 'center',
- color: '#333333',
- marginBottom: 5,
- },
- });
- AppRegistry.registerComponent('ywq', () => ywq);
运行结果如下所示:
点击之前:
调用原生方法并且等待3s后:
再说一个值得注意的地方,一般我们在接收到原生模块主动发来的事件时,都会进行一些操作,如更新UI,而不仅仅是弹出alert 。
例如我们需要更新UI,代码如下:
- /**
- * Sample React Native App
- * https://github.com/facebook/react-native
- * @flow
- */
- import React, { Component } from 'react';
- import {
- AppRegistry,
- StyleSheet,
- Text,
- DeviceEventEmitter,
- NativeModules,
- View
- } from 'react-native';
- export default class ywq extends Component {
- componentWillMount(){
- //监听事件名为EventName的事件
- DeviceEventEmitter.addListener('EventName', function() {
- this.showState();
- alert("send success");
- });
- }
- constructor(props) {
- super(props);
- this.state = {
- content: '这个是预定的接受信息',
- }
- }
- render() {
- return (
- <View style={styles.container}>
- <Text style={styles.welcome}
- onPress={this.callNative.bind(this)}
- >
- 当你点我的时候会调用原生方法,原生方法延迟3s后会向前端发送事件。
- 前端一直在监听该事件,如果收到,则给出alert提示!
- </Text>
- <Text style={styles.welcome} >
- {this.state.content}
- </Text>
- </View>
- );
- }
- callNative()
- {
- NativeModules.MyModule.NativeMethod();
- }
- showState()
- {
- this.setState({content:'已经收到了原生模块发送来的事件'})
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- },
- instructions: {
- textAlign: 'center',
- color: '#333333',
- marginBottom: 5,
- },
- });
- AppRegistry.registerComponent('ywq', () => ywq);
很明显:当收到事件时,改变一个文本框的内容,即更新UI。
运行结果如下,说明在此function中不能使用this,也就是我们并不能更新UI。
那我们能做到在接收到事件后更新UI等后续操作吗?
使用胖箭头函数(Fat arrow functions)
修改UI代码如下:
- /**
- * Sample React Native App
- * https://github.com/facebook/react-native
- * @flow
- */
- import React, { Component } from 'react';
- import {
- AppRegistry,
- StyleSheet,
- Text,
- DeviceEventEmitter,
- NativeModules,
- View
- } from 'react-native';
- export default class ywq extends Component {
- componentWillMount(){
- //监听事件名为EventName的事件
- DeviceEventEmitter.addListener('EventName', ()=> {
- this.showState();
- alert("send success");
- });
- }
- constructor(props) {
- super(props);
- this.state = {
- content: '这个是预定的接受信息',
- }
- }
- render() {
- return (
- <View style={styles.container}>
- <Text style={styles.welcome}
- onPress={this.callNative.bind(this)}
- >
- 当你点我的时候会调用原生方法,原生方法延迟3s后会向前端发送事件。
- 前端一直在监听该事件,如果收到,则给出alert提示!
- </Text>
- <Text style={styles.welcome} >
- {this.state.content}
- </Text>
- </View>
- );
- }
- callNative()
- {
- NativeModules.MyModule.NativeMethod();
- }
- showState()
- {
- this.setState({content:'已经收到了原生模块发送来的事件'})
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#F5FCFF',
- },
- welcome: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
- },
- instructions: {
- textAlign: 'center',
- color: '#333333',
- marginBottom: 5,
- },
- });
- AppRegistry.registerComponent('ywq', () => ywq);
运行之后,界面刷新了。
React native和原生之间的通信的更多相关文章
- React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块
尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息. ...
- React Native 导入原生Xcode项目总结与记录
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- React Native移植原生Android
(一)前言 之前已经写过了有关React Native移植原生Android项目的文章,不过因为RN版本更新的原因吧,跟着以前的文章可能会出现一些问题,对于初学者来讲还是会有很多疑难的困惑的,而且官方 ...
- React Native之原生模块的开发(Android)学习笔记
目录 1.为什么我们需要原生模块开发 2.开发Android原生模块的主要流程 3.原生模块开发实战 1.为什么我们需要原生模块开发? 我们在用RN开发App的时候,有时候需要用到一些原生模块 ...
- [转]Shared——React Native与原生关系理解与对比
零.关系理解 这个是我对RN和原生关系的理解.简单解释下这个图. RN js编写完业务代码后,通过react-native bundle命令,将代码分别编译成一个index.ios.bundle和in ...
- React Native与原生项目连接与发布
前面的各种环境配置按照官方文档一步一步来,挺详细,宝宝在这里就不多说废话了. 其次,前面的配置,我参照的这个博主的文章React Native 集成到iOS原生项目 下面是宝宝掉过的坑(半径15M): ...
- 【React Native开发】React Native移植原生Android项目(4)
),React Native技术交流4群(458982758),请不要反复加群!欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客左側欢迎微信扫描关注订阅号,移动技术干货,精彩文章 ...
- react native与原生的交互
一.交互依赖的重要组件 react native 中如果想要调用ios 中相关的方法,必须依赖一个重要的组件nativemodules import { NativeModules } from ' ...
- React native中的组建通知通信:
有这么一个需求,在B页面pop()回到A页面,需要A页面执行刷新,那么我们可以采用以下方法: 1:在A页面Push到B页面中,加上一个A页面中的刷新函数做为参数,然后在B页面中在pop()函数封装后通 ...
随机推荐
- hadoop一键安装伪分布式
hadoop伪分布式和hive在openSUSE中的安装 在git上的路径为:https://github.com/huabingood/hadoop--------/tree/master 各个文件 ...
- “百度杯”CTF比赛 九月场_123(文件备份,爆破,上传)
题目在i春秋ctf训练营 翻看源码,发现提示: 打开user.php,页面一片空白,参考大佬的博客才知道可能会存在user.php.bak的备份文件,下载该文件可以得到用户名列表 拿去burp爆破: ...
- [POJ 2248]Addition Chains
Description An addition chain for n is an integer sequence with the following four properties: a0 = ...
- [HNOI 2011]XOR和路径
Description 给定一个无向连通图,其节点编号为 1 到 N,其边的权值为非负整数.试求出一条从 1 号节点到 N 号节点的路径,使得该路径上经过的边的权值的“XOR 和”最大.该路径可以重复 ...
- 【Aho-Corasick automation 大米饼模板】
自动机要打熟.自动机要打好.自动机要打得美妙. [例子:HDU2222] #include<stdio.h> #include<queue> #include<cstri ...
- Hdu 5595 GTW likes math
题意: 问题描述 某一天,GTW听了数学特级教师金龙鱼的课之后,开始做数学<从自主招生到竞赛>.然而书里的题目太多了,GTW还有很多事情要忙(比如把妹),于是他把那些题目交给了你.每一道题 ...
- Ubuntu 16.04安装JDK/JRE并配置环境变量
作为一个Linux新手,在写这篇文章之前,安装了几次jdk,好多次都是环境变量配置错误,导致无法登录系统.经过几天的研究,今天新装系统,从头来完整配置一遍 系统版本:Ubuntu 16.04 JDK版 ...
- 笔记7 AOP练习<有疑问>
场景描述: 核心业务:举行一场古典音乐会. 周边功能:观众入场,关闭手机.落座,觉得音乐好听时鼓掌,觉都不好听则退票.(切面) 1.编写切点(切点用于准确定位应该在什么地方应用切面的通 知)----即 ...
- 我在 B 站学习深度学习(生动形象,跃然纸上)
我在 B 站学习深度学习(生动形象,跃然纸上) 视频地址:https://www.bilibili.com/video/av16577449/ tensorflow123 http://tensorf ...
- HashSet与TreeSet
1.TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值 2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个nu ...