SoFunction
Updated on 2025-04-11

Methods for native communication between React Native and Android

When we use React Native for hybrid development, we must communicate and interact with React Native natively. This article is about sharing several ways for native modules and JS to pass data.

The overall steps can be divided into the following points:

  1. Define the Module class on the native side, inherit the ReactContextBaseJavaModule, and define the interactive method in the Module class.
  2. Define the Package class, inherit ReactPackage, and add Module instances to the collection.
  3. In the ReactApplication inherited by Android, the callback implements the getPackages method and adds the Package instance to the collection under getPackages.

The following is the example code of the Mudule class. In order to facilitate everyone's understanding, I posted all the codes and explained them one by one.

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class ToastExample extends ReactContextBaseJavaModule{
  private static final String LONG_TIME = "LONG";
  private static final String SHORT_TIME = "SHORT";
  private static final String MESSAGE = "MESSAGE";

  public ToastExample(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "ToastForAndroid";
  }

  @ReactMethod
  public void getDataFromIntent(Callback callback){
    try{
      Activity currentActivity=getCurrentActivity();
      String result =().getStringExtra("data");
      if((result)){
        ("no_data");
      }else{
        (result);
      }
    }catch (Exception e){
      ("error");
    }
  }

  @Override
  public Map<String, Object> getConstants() {
    //Let js use these constants    Map<String,Object> constants = new HashMap<>();
    (LONG_TIME, Toast.LENGTH_LONG);
    (SHORT_TIME,Toast.LENGTH_SHORT);
    (MESSAGE,"getConstants");
    return constants;
  }

  @ReactMethod
  public void show(int duration){
    (getReactApplicationContext(),"message:"+duration,duration).show();
  }

  @ReactMethod
  public void sendEvent(){
    onScanningResult();
  }

  @ReactMethod
  public void testAndroidCallbackMethod(String msg, Callback callback){
    (getReactApplicationContext(),msg,Toast.LENGTH_LONG).show();
    ("abc");
  }

  @ReactMethod
  public void textAndroidPromiseMethod(String msg, Promise promise){
    (getReactApplicationContext(),msg,Toast.LENGTH_SHORT).show();
    String result="Xie Hanjie";
    (result);
  }

  public void onScanningResult(){
    WritableMap params = ();
    ("key", "myData");
    sendEvent(getReactApplicationContext(),"EventName",params);
  }

  public static void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
    ().emit(eventName, params);
  }

  public void nativeCallRn(){
    onScanningResult();
  }

  @Override
  public boolean canOverrideExistingModule() {
    return true;
  }
}

In the above Module code, the name returned by the getName() method is that the name returned in the RN code is required to call the method of the class. The method under @ReactMethod annotation is our custom method, indicating that this method can be called by rn. As for the above four forms of methods and other steps, it will be explained in detail.

The custom ReactPackage code is as follows:

import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class ExampleReactNativePackage implements ReactPackage{

  public ToastExample toastExample;
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    toastExample=new ToastExample(reactContext);
    (toastExample);
    return modules;
  }

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return ();
  }
}

This step is very simple, just add the ToastExample class above to NativeModule

Then the third step is also very simple, the code is as follows

import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class MyApplication extends Application implements ReactApplication{
  public static final ExampleReactNativePackage exampleReactNativePackage=new ExampleReactNativePackage();
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return ;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          exampleReactNativePackage
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }
}

This is not just adding the ExampleReactNativePackage to the ReactPackage, it is also very simple.

For this reason, the entire Android native has been written. Next is to write a js end, and the following is an example of a js end: (To put nonsense, I usually like to post all the codes to explain them one by one, which is more coherent)

import React from 'react';
import {
 AppRegistry,
 StyleSheet,
 Text,
 View,
 TouchableOpacity,
 ToastAndroid,
 NativeModules,
 DeviceEventEmitter
} from 'react-native';

export default class HelloWorld extends  {

  constructor(props){
    super(props);
    ={
       text1:'ToastForAndroid',
       text2:'testAndroidCallbackMethod',
       text3:'textAndroidPromiseMethod',
       text4:'DeviceEventEmitter',
       text5:'getValue',
       data:'no_data',
    }
  }

  componentWillMount() {
    ('EventName', function (msg) {
      (msg);
      let rest=;
      ("DeviceEventEmitter received the message:" + "\n" + rest, )
    });
    ((result)=&gt;{
      ({data:result});
    });
  }

  render() {
   return (
     &lt;View style={}&gt;
      &lt;Text&gt;{}&lt;/Text&gt;
      &lt;TouchableOpacity onPress={this._onPressButton.bind(this)}&gt;
         &lt;Text style={}&gt;{.text1}&lt;/Text&gt;
      &lt;/TouchableOpacity&gt;
      &lt;TouchableOpacity onPress={this._onPressButton2.bind(this)}&gt;
         &lt;Text style={}&gt;{.text2}&lt;/Text&gt;
      &lt;/TouchableOpacity&gt;
      &lt;TouchableOpacity onPress={this._onPressButton3.bind(this)}&gt;
         &lt;Text style={}&gt;{.text3}&lt;/Text&gt;
      &lt;/TouchableOpacity&gt;
      &lt;TouchableOpacity onPress={this._onPressButton4.bind(this)}&gt;
         &lt;Text style={}&gt;{.text4}&lt;/Text&gt;
      &lt;/TouchableOpacity&gt;
      &lt;TouchableOpacity onPress={this._onPressButton5.bind(this)}&gt;
         &lt;Text style={}&gt;{.text5}&lt;/Text&gt;
      &lt;/TouchableOpacity&gt;
     &lt;/View&gt;
    )
  }
  _onPressButton(){
    (1000);
  }
  _onPressButton2(){    ("HelloJack",(result)=&gt;{
      ({text:result});
    });
  }
  _onPressButton3(){    ("abcx").then((result)=&gt;{
         ({text3:result});
       }).catch((error)=&gt;{
         ({text:'error'});
       })
  }
  _onPressButton4(){
    ();
  }
  _onPressButton5(){
     (, )
  }

}
  var styles = ({
   container: {
    flex: 1,
    justifyContent: 'center',
    flexDirection: 'column',
   },
   hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
   },
  });
('HelloWorlds', () =&gt; HelloWorld);

This is the call instance of the entire js side. In the React Naitve layer, the RN side can adjust the native method through NativeModules.[module name].[Method name], and the passed parameters can also be obtained through the RN side through NativeModules.[module name].[Parameter name]. The specific usage is as above code.

For native calls to the methods in React Native, we can use RCTDeviceEventEmitter method. This method is equivalent to broadcasting in Android. The specific corresponding native code is as follows:

();

It is also coherent with the above code.

Finally, summarize the four ways of interaction

The first one is the simplest, as in the above code

@ReactMethod
 public void show(int duration){
  (getReactApplicationContext(),"message:"+duration,duration).show();
 }

That is, use the ReactMethod annotation method to call native

Callback callback method, like the above code

@ReactMethod
 public void testAndroidCallbackMethod(String msg, Callback callback){
  (getReactApplicationContext(),msg,Toast.LENGTH_LONG).show();
    ("abc");
}

The corresponding js code is

_onPressButton2(){
  ("HelloJack",(result)=>{
      ({text:result});
  });
}

That is, you pass in parameters to operate and then give you the callback result

The callback method is similar to RxJava. Complex code structures can be converted into short and easy-to-read code through chaining. As shown in the above code

@ReactMethod
  public void textAndroidPromiseMethod(String msg, Promise promise){
    (getReactApplicationContext(),msg,Toast.LENGTH_SHORT).show();
    String result="Xie Hanjie";
    (result);
  }

The corresponding js code is

_onPressButton3(){
    ("abcx").then((result)=>{
         ({text3:result});
       }).catch((error)=>{
         ({text:'error'});
       })
  }

The JS side obtains the Promise data through the then interface, and returns error information when the execution error is performed.

Through event method: RCTDeviceEventEmitter, generally native calls React Native, which is equivalent to broadcast. The corresponding code above is as follows:

public static void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
    ().emit(eventName, params);
  }

The corresponding js code is

('EventName', function (msg) {
      (msg);
      let rest=;
      ("DeviceEventEmitter received the message:" + "\n" + rest, )
  });

Native sends native events and then React Native registers to listen to get information.

Here is an example of our actual combat, which is to start the RN interface and pass data. How to do it? Beginners at the beginning still couldn't react at once. The starting point was very simple. Just use our examples above.

First, native startup code

Intent intent=new Intent(,);
("data","HelloJack");
startActivity(intent);

The final thing is to add it to the ToastExample class above

@ReactMethod
  public void getDataFromIntent(Callback callback){
    try{
      Activity currentActivity=getCurrentActivity();
      String result =().getStringExtra("data");
      if((result)){
        ("no_data");
      }else{
        (result);
      }
    }catch (Exception e){
      ("error");
    }
  }

Then get it on the RN side

((result)=>{
  ({data:result});
});

Similarly, please refer to other situationsRN's Android: Inter-call and data transfer between native interface and React interface, This is also one of my references.

Finally, I present the source code that everyone is most looking forward to/jack921/ReactNativeParamIf you don't understand anything, just open source code

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.