Android React Native原生模块与JS模块通信的方法总结

Android React Native原生模块与JS模块通信的方法总结,第1张

概述AndroidReactNative原生模块与JS模块通信的方法总结前言:在做ReactNative开发的时候避免不了的需要原生模块和JS之间进行数据传递,这篇文章将向大家分享原生模块向JS传递数据的几种方式。

AndroID React Native原生模块与Js模块通信的方法总结

前言:

在做React Native开发的时候避免不了的需要原生模块和Js之间进行数据传递,这篇文章将向大家分享原生模块向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,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,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,height,} = await RNTest.measureLayout(100,100);  console.log(relativeX + ':' + relativeY + ':' + wIDth + ':' + height);  } catch (e) {  console.error(e); }}

在上述代码中,通过ES7的新特性async/await来修饰了test方法,来以同步方式调用原生模块的measureLayout方法,如果原生模块处理成功,

那么Js中relativeX,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传递事件。

在原生模块中:

@OverrIDepublic 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(eventname,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) 来移除对名为“onScanningResult”事件的监听。

另外,Js模块也支持通过Subscribable mixin,也注册监听事件,因为ES6已经不再推荐使用mixin,所以在这里也就不向大家介绍了。

三种方式的优缺点

方式 缺点 优点
通过Callbacks的方式 只能传递一次 传递可控,Js模块调用一次,原生模块传递一次
通过Promises的方式 只能传递一次 传递可控,Js模块调用一次,原生模块传递一次
通过发送事件的方式 原生模块主动传递,Js模块被动接收 可多次传递

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

以上是内存溢出为你收集整理的Android React Native原生模块与JS模块通信的方法总结全部内容,希望文章能够帮你解决Android React Native原生模块与JS模块通信的方法总结所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147000.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存