首页 React Native原生模块与JS模块通信的几种方式

React Native原生模块与JS模块通信的几种方式

举报
开通vip

React Native原生模块与JS模块通信的几种方式React Native原生模块与JS模块通信的几种方式 方式一:通过Callbacks的方式 说起Callbacks大家都不陌生,它是最常用的设计模式之一。无论是Java,Object-c,C#,还是JavaScript等都会看到Callbacks的身影。 原生模块支持Callbacks类型的参数,该Callbacks对应JS中的function。 在原生模块中: public class RNTestModule extends ReactContextBaseJavaModule{ public...

React Native原生模块与JS模块通信的几种方式
React Native原生模块与JS模块通信的几种方式 方式一:通过Callbacks的方式 说起Callbacks大家都不陌生,它是最常用的设计模式之一。无论是Java,Object-c,C#,还是JavaScript等都会看到Callbacks的身影。 原生模块支持Callbacks类型的参数,该Callbacks对应JS中的function。 在原生模块中: public class RNTestModule extends ReactContextBaseJavaModule{ public RNTestModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "RNTest"; } @ReactMethod public void measureLayout( int tag, int ancestorTag, Callback errorCallback, Callback successCallback) { try { measureLayout(tag, ancestorTag, mMeasureBuffer); map.putDouble("relativeX",1); map.putDouble("relativeY", 1); map.putDouble("width", 2); map.putDouble("height",3); successCallback.invoke(relativeX, relativeY, width, height); } catch (IllegalViewOperationException e) { errorCallback.invoke(e.getMessage()); } } 在上述代码中,measureLayout方法的参数中后两个就是Callbacks,当原生模块处理成功时通过successCallback回调来告知JS处理成功的结果,当原生模块发生异常时,则通过errorCallback 回调来JS处理异常。 在JS模块中: RNTest.measureLayout( 100, 100, (msg) => { console.log(msg); }, (x, y, width, height) => { console.log(x + ':' + y + ':' + width + ':' + height); } 上述代码,是在JS模块中调用原生模块的方法measureLayout,同时向它传递了四个参数,后两个是function类型的参数用于接收原生模块的处理结果。 通过上述的方式,JS调用原生模块的measureLayout方法,原生模块则通过errorCallback与successCallbackCallbacks来将处理结果传递到JS。 这种“You call me,I will callback”,的方式小伙伴们都看懂了吧。 方式二:通过Promises的方式 Promises是ES6的一个新的特性,在React Native中你会看到Promises的大量使用。 原生模块也是支持Promises的,这对喜欢使用Promises的小伙伴则是一个很好的消息。 在原生模块中: public class RNTestModule extends ReactContextBaseJavaModule{ public RNTestModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "RNTest"; } @ReactMethod public void measureLayout( int tag, int ancestorTag, Promise promise) { try { Writablemap map = Arguments.createMap(); map.putDouble("relativeX",1); map.putDouble("relativeY", 1); map.putDouble("width", 2); map.putDouble("height",3); promise.resolve(map); } catch (IllegalViewOperationException e) { promise.reject(e); } } } 上述代码中,measureLayout方法接收的最后一个为Promise,当相应的处理结果出来之后原生模块通过调用Promise的相应方法来向JS模块传递处理成功,或处理失败的数据。 提示:在原生模块中Promise类型的参数要放在最后一位,这样JS调用的时候才能返回一个Promise。 在JS模块中: async test() { try { var { relativeX, relativeY, width, height, } = await RNTest.measureLayout(100, 100); console.log(relativeX + ':' + relativeY + ':' + width + ':' + height); } catch (e) { console.error(e); } } 在上述代码中,通过ES7的新特性async/await来修饰了test方法,来以同步方式调用原生模块的measureLayout方法,如果原生模块处理成功,那么JS中relativeX,relativeY,width,height会获得相应的值,如果原生模块处理失败,则会抛出异常。 如果,不希望以同步的形式调用,可以这样写: test2(){ RNTest.measureLayout(100,100).then(e=>{ console.log(e.relativeX + ':' + e.relativeY + ':' + e.width + ':' + e.height); this.setState({ relativeX:e.relativeX, relativeY:e.relativeY, width:e.width, height:e.height, }) }).catch(error=>{ console.log(error); }); 以上就是通过Promises的方式向JS传递数据的方式,小伙伴们看懂了吗。 上述两种方式,通过Callbacks的方式与通过Promises的方式,都可以向JS模块传递数据,但都是只能传递一次。 如果,你需要多次向JS模块传递数据(如:按键事件)上述方式还是不够好,下面就像大家分享可以多次传递数据的方式。 方式三:通过发送事件的方式 原生模块支持另外一种向JS模块传递数据的方式,通过发送事件的方式。 原生模块,可以向JS传递事件而不要而不需要直接的调用,就像Android中的广播,iOS中的通知中心。 下面就向大家演示通过RCTDeviceEventEmitter,来向JS传递事件。 在原生模块中: @Override public void onHandleResult(String barcodeData) { Writablemap params = Arguments.createMap(); params.putString("result", barcodeData); sendEvent(getReactApplicationContext(), "onScanningResult", params); } private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) { reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(evewww.tt951.comntName, params); } 上述代码向JS模块发送了一个名为“onScanningResult”的事件,并携带了“params”作为参数。 在JS模块中: 下面是在JS代码中进行监听原生模块发出的名为“onScanningResult”的事件。 componentDidMount() { //注册扫描监听 DeviceEventEmitter.addListener('onScanningResult',this.onScanningResult); } onScanningResult = (e)=> { this.setState({ scanningResult: e.result, }); // DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult);//移除扫描监听 在JS中通过DeviceEventEmitter注册监听了名为“onScanningResult”的事件,当原生模块发出名为“onScanningResult”的事件后,绑定在该事件上的onScanningResult = (e)会被回调。 然后通过e.result就可获得事件所携带的数据。 心得:如果在JS中有多处注册了onScanningResult事件,那么当原生模块发出事件后,这几个地方会同时收到该事件。不过大家也可以通过DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult) 来移除对名为“onScannwww.baiyuewang.netingResult”事件的监听。 另外,JS模块也支持通过Subscribable mixin,也注册监听事件,因为ES6已经不再推荐使用mixin,所以在这里也就不向大家介绍了。 三种方式的优缺点 方式缺点优点 通过Callbacks的方式只能传递一次传递可控,JS模块调用一次,原生模块传递一次 通过Promises的方式只能传递一次传递可控,JS模块调用一次,原生模块传递一次 通过发送事件的方式原生模块主动传递,JS模块被动接收可多次传递
本文档为【React Native原生模块与JS模块通信的几种方式】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_014457
暂无简介~
格式:doc
大小:26KB
软件:Word
页数:0
分类:互联网
上传时间:2019-08-23
浏览量:18