真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

AndroidReactNative原生模塊與JS模塊通信的方法總結

Android React Native原生模塊與JS模塊通信的方法總結

創(chuàng)新互聯(lián)長期為上千多家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為余干企業(yè)提供專業(yè)的成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設,余干網(wǎng)站改版等技術服務。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

前言:

在做React Native開發(fā)的時候避免不了的需要原生模塊和JS之間進行數(shù)據(jù)傳遞,這篇文章將向大家分享原生模塊向JS傳遞數(shù)據(jù)的幾種方式。

方式一:通過Callbacks的方式

說起Callbacks大家都不陌生,它是最常用的設計模式之一。無論是Java,Object-c,C#,還是JavaScript等都會看到Callbacks的身影。

原生模塊支持Callbacks類型的參數(shù),該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方法的參數(shù)中后兩個就是Callbacks,當原生模塊處理成功時通過successCallback回調(diào)來告知JS處理成功的結果,當原生模塊發(fā)生異常時,則通過errorCallback回調(diào)來JS處理異常。

在JS模塊中:

RNTest.measureLayout(
 100,
 100,
 (msg) => {
  console.log(msg);
 },
 (x, y, width, height) => {
  console.log(x + ':' + y + ':' + width + ':' + height);
 }
);

上述代碼,是在JS模塊中調(diào)用原生模塊的方法measureLayout,同時向它傳遞了四個參數(shù),后兩個是function類型的參數(shù)用于接收原生模塊的處理結果。

通過上述的方式,JS調(diào)用原生模塊的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,當相應的處理結果出來之后原生模塊通過調(diào)用Promise的相應方法來向JS模塊傳遞處理成功,或處理失敗的數(shù)據(jù)。

提示:在原生模塊中Promise類型的參數(shù)要放在最后一位,這樣JS調(diào)用的時候才能返回一個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方法,來以同步方式調(diào)用原生模塊的measureLayout方法,如果原生模塊處理成功,

那么JS中relativeX,relativeY,width,height會獲得相應的值,如果原生模塊處理失敗,則會拋出異常。

如果,不希望以同步的形式調(diào)用,可以這樣寫:

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傳遞數(shù)據(jù)的方式,小伙伴們看懂了嗎。

上述兩種方式,通過Callbacks的方式與通過Promises的方式,都可以向JS模塊傳遞數(shù)據(jù),但都是只能傳遞一次。

如果,你需要多次向JS模塊傳遞數(shù)據(jù)(如:按鍵事件)上述方式還是不夠好,下面就像大家分享可以多次傳遞數(shù)據(jù)的方式。

方式三:通過發(fā)送事件的方式

原生模塊支持另外一種向JS模塊傳遞數(shù)據(jù)的方式,通過發(fā)送事件的方式。

原生模塊,可以向JS傳遞事件而不要而不需要直接的調(diào)用,就像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(eventName, params);
}

上述代碼向JS模塊發(fā)送了一個名為“onScanningResult”的事件,并攜帶了“params”作為參數(shù)。

在JS模塊中:

下面是在JS代碼中進行監(jiān)聽原生模塊發(fā)出的名為“onScanningResult”的事件。

componentDidMount() {
  //注冊掃描監(jiān)聽
  DeviceEventEmitter.addListener('onScanningResult',this.onScanningResult);
}
onScanningResult = (e)=> {
  this.setState({
    scanningResult: e.result,
  });
  // DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult);//移除掃描監(jiān)聽
}

在JS中通過DeviceEventEmitter注冊監(jiān)聽了名為“onScanningResult”的事件,當原生模塊發(fā)出名為“onScanningResult”的事件后,綁定在該事件上的onScanningResult = (e)會被回調(diào)。

然后通過e.result就可獲得事件所攜帶的數(shù)據(jù)。

心得:如果在JS中有多處注冊了onScanningResult事件,那么當原生模塊發(fā)出事件后,這幾個地方會同時收到該事件。不過大家也可以通過DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult) 來移除對名為“onScanningResult”事件的監(jiān)聽。

另外,JS模塊也支持通過Subscribable mixin,也注冊監(jiān)聽事件,因為ES6已經(jīng)不再推薦使用mixin,所以在這里也就不向大家介紹了。

三種方式的優(yōu)缺點

方式缺點優(yōu)點
通過Callbacks的方式只能傳遞一次傳遞可控,JS模塊調(diào)用一次,原生模塊傳遞一次
通過Promises的方式只能傳遞一次傳遞可控,JS模塊調(diào)用一次,原生模塊傳遞一次
通過發(fā)送事件的方式原生模塊主動傳遞,JS模塊被動接收可多次傳遞

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


分享標題:AndroidReactNative原生模塊與JS模塊通信的方法總結
網(wǎng)頁網(wǎng)址:http://weahome.cn/article/pejhph.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部