写在前面:最近在学习RN时,了解互相通信的问题,RN提供了三种方式.另外自定义ReactContextBaseJavaModule其实也是可以的,但单纯调用某个方法相对使用麻烦,一般用于封装调用.
大致分为2种情况:
-
Android主动向JS端传递事件、数据
-
JS端被动向Android询问获取事件、数据
@H_404_19@
方式 | 优点 | 缺点 |
---|---|---|
事件方式:RCTDeviceEventEmitter | 可任意时刻传递,Native主导控制 | 个人觉得此种方式缺点小 |
CallBack回调方式 | JS调用一次,Native返回一次 | CallBack为异步操作,返回时机不确定 |
Promises 方式 | 每次使用需要JS调用一次 |
效果图:
①:Android向JS传递事件
采用RCTDeviceEventEmitter:
在Native模块:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36 @H_404_19@
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36 @H_404_19@//延迟0.1秒获取时间。 @ReactMethod public void getTime() { new Thread(new Runnable() { @Override void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } SimpleDateFormat formatDate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date date = new Date(System.currentTimeMillis()); String time = formatDate.format(date); WritableMap writableMap = new WritableNativeMap(); writableMap.putString("key",time); sendTransMisson(mReactContext,"EventName",writableMap); } }).start(); } /** * @param reactContext * @param eventName 事件名 * @param params 传惨 */ void sendTransMisson(ReactContext reactContext,String eventName,@Nullable WritableMap params) { reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName,params); }
getTime()主要为JS端调用Native的方法,在内部调用
sendTransMisson进行事件发送。 sendTransMisso这个方法名可以任意取
你喜欢就好,内部参数eventName为事件名,params为传递的事件属性。
在JS端接受:
- 1
- 2
- 3
- 4
- 5
- 6
- 7 @H_404_19@componentWillMount() { DeviceEventEmitter.addListener('EventName',function (msg) { console.log(msg); ToastAndroid.show("DeviceEventEmitter收到消息:" + "\n" + msg.key,ToastAndroid.SHORT) }); }
- CallBack回调接受: @H_404_19@
在componentWillMount进行监听事件获取传递的事件信息。
②:JS被动向Android询问事件、信息
Native部分:
- 1
- 2
- 3
- 4 @H_404_19@void callBackTime(String name,Callback callback){ callback.invoke(getTimeMillis()); }
CallBack对应的就是JS中的function,JS调用Native模块处理完毕以后将时间回调给JS端。
JS端发送:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10 @H_404_19@getCallBackTime() { NativeModules@H_766_404@.TransMissonMoudle.callBackTime("Allure",(msg) => { console.log(msg); ToastAndroid.show("CallBack收到消息:"+msg,ToastAndroid.SHORT) } ); }
向Native发送了一个名字Allure,在第二个参数接收回调结果。
Callback通俗简单易懂。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8 @H_404_19@void sendPromiseTime(String name,Promise promise) { WritableMap writableMap=new WritableNativeMap(); writableMap.putString("age",0); Box-sizing: border-Box;">"20"); writableMap.putString("time",getTimeMillis()); promise.resolve(writableMap); }
在此方法,接受了一个JS端传来的name,并且回传给JS端了一个字典,并存储了age和time两个字段。 需要注意的是使用Promise时,Promise参数需要放在最后一个参数里,否则JS接搜不到消息。
JS端:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13 @H_404_19@getPromiseTime() { NativeModules.sendPromiseTime("Allure").then(msg=> { console.log("年龄:" + msg.age + "/n" + "时间:" + msg.time); ToastAndroid"Promise收到消息:" + "\n" + .time,68); Box-sizing: border-Box;">.SHORT) this.setState({ age: msg.age,time: msg.catch(error=> { console.log(error); }); }
JS端通过then接口来获取Promise的数据。