React Native Bridging Modules for Android from Scratch on Windows

When using React Native to write mobile apps, JavaScript is the primary programming language. However, sometimes, you may want to call a platform API that not supported by existing React Native component or use a third-party Android library that built as an AAR file. For these cases, you need to write native code for bridging using Android Studio and Xcode. In this article, I will demonstrate how to create a simplest React Native Bridge module step by step.

Prerequisites

React Native Bridge Module: Hello World

Here is my project structure:

--Project folder

  --package.json

  --android // a folder that contains Java code for native module

  --index.js

Package.json

Create an empty folder named react-native-helloworld, which is also the module name. Initialize the project:

cd react-native-helloworld
npm init

react native module init

There is a package.json file generated.

Android

Create a simple Android project. You can refer to React Native docs:

react native android

MyModule extends ReactContextBaseJavaModule class and implements the functionality required by the JavaScript.

package com.yushulx.helloworld;

import android.widget.Toast;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class MyModule extends ReactContextBaseJavaModule {

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

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

  @ReactMethod
  public void alert(String message) {
    Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show();
  }
}

The string returned by getName() has to be same as the class name. Here it is MyModule.

MyPackage is used to register the module.

package com.yushulx.helloworld;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyPackage implements ReactPackage {

  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
  }

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

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

    modules.add(new MyModule(reactContext));

    return modules;
  }

}

Index.js

This file is used to wrap the native module in a JavaScript module.

import {NativeModules} from 'react-native';
module.exports = NativeModules.MyModule;

So far, we have finished the React Native module.

React Native Example

Create a React Native project:

react-native init Example

Since all Node modules should be installed under {React Native project}\node_modules\, we need to add the project directory of the bridging module to the package.json file of the React Native project.

"dependencies": {
	"react": "16.0.0-alpha.6",
	"react-native": "0.43.3",
	"react-native-helloworld":"file:../"
},

Install the module:

npm install

react native install module

Link the dependency:

react-native link

This command will cause some file changes.

  • android\settings.gradle
    include ':react-native-helloworld'
    project(':react-native-helloworld').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-helloworld/android')
    
  • android\app\build.gradle
    dependencies {
        compile project(':react-native-helloworld')
    }
    
  • android\app\src\main\java\com\example\MainApplication.java
    import com.yushulx.helloworld.MyPackage;
    protected List<ReactPackage> getPackages() {
          return Arrays.<ReactPackage>asList(
              new MainReactPackage(), 
              new MyPackage()
          );
        }
    

Use the custom React Native module in index.android.js:

import MyModule from 'react-native-helloworld';

const onButtonPress = () => {
  MyModule.alert('Hello World');
};

export default class Example extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Button title='Click' onPress={onButtonPress}/>
      </View>
    );
  }
}

Run the Android app:

react native android app

Source Code

https://github.com/yushulx/react-native-helloworld