Sign in
Log inSign up
Building custom Android modules for React Native

Building custom Android modules for React Native

Sriraman's photo
Sriraman
·Jul 7, 2016

React Native applications have two sides (React's JavaScript side and the Android side). Assume these two sides are two sides of a river. Obviously, you need a bridge to cross this river. The React Native team built bridges for major things like Camera, Fingerprint, Scanner, etc... But they can’t cover every feature in Android. So, they gave us the tools to build our bridges.

I was using AsyncStorage to store the user preferences in my React Native app. But, the value stored by the AsyncStorage was not accessible from the Java layer of Android. So, I was starting my JavaScriptCore whenever my background service needed the user preferences. Then we decided to store the user preferences in Android’s Native Shared Preferences. I was searching for a corresponding bridge, on Google, and js.coach. But, there was no bridge to store the Shared Preferences from the React Native's layer. I decided to create one.

To view the final repo, click here

Creating the first module

First, create an AndroidManifest.xml file with your package name.

<manifest 
    xmlns:android=”http://schemas.android.com/apk/res/android"
    package=”in.sriraman.sharedpreferences”
>
</manifest>

We have to create the module by extending the ReactContextBaseModule. The first step is to override the name of the module.

@Override
public String getName(){
 return “SharedPreferences”;
}

I have already created a Java function to handle the data in Shared Preferences. Check the SharedHandler.java and SharedDataProvider.java to know how the Shared Preferences work inside the Java layer. Here, I have exposed three functions putSharedValue(key, value), getSharedValue(key) and clear(). These three functions can be accessed from our module.

We have to annotate the function with @ReactMethod for react methods.

@ReactMethod
public void setItem(String key, String value) {
    SharedHandler.init(getReactApplicationContext());
    SharedDataProvider.putSharedValue(key,value);
}

I have initialised the SharedHandler with the application context provided by getReactApplicationContext(). Then I can call the function to execute the particular task.

In the previous ReactMethod, We didn’t have the requirement to send back anything to the JavaScript layer. When we want to get the value from Shared Preferences, we should send a callback. Sending a callback can be done as follows:

@ReactMethod
public void getItem(String key, Callback successCallback){
     SharedHandler.init(getReactApplicationContext());
     String value = SharedDataProvider.getSharedValue(key);
     successCallback.invoke(value);
}

If we need to send a callback, then we should send an extra parameter for SuccessCallback. The callback can be sent back to the JavaScript layer using the successCallback.invoke() function. If you also need an error callback, you can just add an extra parameter in the ReactMethod.

After creating the React Module, we have to register the module. If you don’t register the module, it can’t be accessed from the JavaScript layer. Shared Preferences module is ready. You can directly consume the API in your application, or you can publish it to NPM.

If you are publishing it to NPM, users have to make a few changes to build the Java files inside their Android app. For a detailed explanation of the setup process, you can check this README.md file.