Summary of the method of communicating between Android React Native module and JS module
Preface:
When developing React Native, it is inevitable to pass data between native modules and JS. This article will share with you several ways for native modules to pass data to JS.
Method 1: Through Callbacks
When it comes to Callbacks, it is one of the most commonly used design patterns. Callbacks will be seen in Java, Object-c, C#, or JavaScript.
The native module supports Callbacks type parameters, which corresponds to the function in JS.
In native module:
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); ("relativeX",1); ("relativeY", 1); ("width", 2); ("height",3); (relativeX, relativeY, width, height); } catch (IllegalViewOperationException e) { (()); } }
In the above code, the last two parameters of the measureLayout method are Callbacks. When the native module is successfully processed, the successCallback callback is used to inform the JS of the successful processing. When an exception occurs in the native module, the JS handles the exception through the errorCallback callback.
In the JS module:
( 100, 100, (msg) => { (msg); }, (x, y, width, height) => { (x + ':' + y + ':' + width + ':' + height); } );
The above code is to call the method measureLayout of the native module in the JS module, and pass four parameters to it at the same time. The last two are function-type parameters used to receive the processing results of the native module.
In the above method, JS calls the measureLayout method of the native module, and the native module passes the processing results to JS through errorCallback and successCallbackCallbacks.
Friends can understand this way of "You call me, I will callback".
Method 2: Through Promises
Promises is a new feature of ES6, and in React Native you will see a lot of use of Promises.
Native modules also support Promises, which is good news for those who like to use Promises.
In native module:
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 = (); ("relativeX",1); ("relativeY", 1); ("width", 2); ("height",3); (map); } catch (IllegalViewOperationException e) { (e); } } }
In the above code, the last one received by the measureLayout method is Promise. After the corresponding processing results are released, the native module passes data that has been successfully processed or failed to process to the JS module by calling the corresponding method of Promise.
Tip: In the native module, the parameters of the Promise type must be placed in the last position, so that a Promise can be returned when JS calls it.
In the JS module:
async test() { try { var { relativeX, relativeY, width, height, } = await (100, 100); (relativeX + ':' + relativeY + ':' + width + ':' + height); } catch (e) { (e); } }
In the above code, the test method is modified through the new feature of ES7 async/await to call the measureLayout method of the native module in a synchronous manner. If the native module is successfully processed,
Then relativeX, relativeY, width, height in JS will get the corresponding value. If the native module fails to process, an exception will be thrown.
If you do not want to call in synchronous form, you can write it like this:
test2(){ (100,100).then(e=>{ ( + ':' + + ':' + + ':' + ); ({ relativeX:, relativeY:, width:, height:, }) }).catch(error=>{ (error); }); }
The above is how to pass data to JS through Promises. Do you guys understand?
The above two methods areCallbacks way with PromisesIn the way, data can be passed to JS modules, but they can only be passed once.
If you need to pass data to the JS module multiple times (such as key event) the above method is not good enough, the following is like everyone who shares the way you can pass data multiple times.
Method 3: By sending events
The native module supports another way of passing data to the JS module, by sending events.
Native modules that can pass events to JS without direct calls, just like broadcast in Android and notification center in iOS.
Next, I will demonstrate to you that events are passed to JS through RCTDeviceEventEmitter.
In native module:
@Override public void onHandleResult(String barcodeData) { WritableMap params = (); ("result", barcodeData); sendEvent(getReactApplicationContext(), "onScanningResult", params); } private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) { () .emit(eventName, params); }
The above code sends an event named "onScanningResult" to the JS module and carries "params" as a parameter.
In the JS module:
The following is an event called "onScanningResult" emitted by the native module in JS code.
componentDidMount() { //Register scan monitoring ('onScanningResult',); } onScanningResult = (e)=> { ({ scanningResult: , }); // ('onScanningResult',);//Remove scan listening}
In JS, the event named "onScanningResult" is listened to through DeviceEventEmitter registration. When the native module issues an event named "onScanningResult", the onScanningResult = (e) bound to the event will be called back.
Then, the data carried by the event can be obtained.
Experience: If there are multiple registered onScanningResult events in JS, then when the native module issues an event, these places will receive the event at the same time. However, you can also remove the listening to the event named "onScanningResult" by ('onScanningResult',).
In addition, the JS module also supports the use of Subscribable mixin and also registers and listens to events. Because ES6 no longer recommends using mixin, I will not introduce it to you here.
Pros and cons of the three methods
Way | shortcoming | advantage |
---|---|---|
Through Callbacks | Only pass once | Passing controllable, JS module is called once, native module is passed once |
Through Promises | Only pass once | Passing controllable, JS module is called once, native module is passed once |
By sending events | Active delivery of native modules, passive reception of JS modules | Can be delivered multiple times |
Thank you for reading, I hope it can help you. Thank you for your support for this site!