When developing cross-platform applications with React Native, there might be instances where you need to access platform-specific features or third-party libraries that are not available in the React Native ecosystem. In such cases, creating custom native modules is a powerful technique to extend React Native’s capabilities. This section focuses on creating custom native modules for Android, allowing you to tap into the native Android APIs and functionalities.

React Native provides a bridge between JavaScript and native code, enabling seamless integration of native modules. By creating custom native modules, you can expose native functionalities to JavaScript, allowing you to use them in your React Native applications. This approach is particularly useful when you need to access hardware features, perform complex computations, or utilize native libraries.

Understanding Native Modules

Native modules are essentially Java classes that are exposed to JavaScript. They are registered with React Native at runtime and can be invoked from JavaScript code. Native modules can return promises or send events to JavaScript, providing a flexible way to interact with native code.

To create a native module, you need to define a Java class that extends the ReactContextBaseJavaModule class. This class is responsible for exposing the native module to JavaScript and implementing the desired functionalities. Let’s explore the process of creating a custom native module for Android step-by-step.

Setting Up Your Development Environment

Before you start creating a custom native module, ensure that your development environment is set up correctly. You need to have Android Studio installed and configured, along with the necessary Android SDKs. Additionally, make sure your React Native project is properly initialized and running.

Creating a Custom Native Module

1. **Create a New Java Class**: In your Android project, navigate to the android/app/src/main/java/com/yourprojectname directory and create a new Java class. This class will represent your custom native module.

2. **Extend ReactContextBaseJavaModule**: Extend the ReactContextBaseJavaModule class in your new Java class. This makes your class a native module that can be registered with React Native.

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

public class MyCustomModule extends ReactContextBaseJavaModule {
    public MyCustomModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

3. **Implement Native Methods**: Define the native methods you want to expose to JavaScript. Annotate these methods with @ReactMethod to make them accessible from JavaScript.

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

4. **Register the Module**: To make your native module available to React Native, you need to register it with the React Native framework. Create a new Java class that implements the ReactPackage interface and override its methods.

import com.facebook.react.ReactPackage;
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 MyCustomPackage implements ReactPackage {
    @Override
    public List createNativeModules(ReactApplicationContext reactContext) {
        List modules = new ArrayList<>();
        modules.add(new MyCustomModule(reactContext));
        return modules;
    }

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

5. **Modify MainApplication.java**: Finally, register your custom package in the MainApplication.java file by adding it to the list of packages returned by the getPackages method.

import com.yourprojectname.MyCustomPackage;

@Override
protected List getPackages() {
    return Arrays.asList(
        new MainReactPackage(),
        new MyCustomPackage() // Add this line
    );
}

Using the Custom Native Module in JavaScript

Once you have created and registered your custom native module, you can use it in your JavaScript code. Import the NativeModules object from react-native and access your custom module.

import { NativeModules } from 'react-native';

const { MyCustomModule } = NativeModules;

MyCustomModule.showToast('Hello from React Native!');

By following these steps, you have successfully created a custom native module for Android in your React Native application. This module can now be used to access native Android functionalities and enhance your app's capabilities.

Handling Asynchronous Operations

Native modules can also handle asynchronous operations by using promises or callbacks. For instance, if you need to perform a network request or a long-running task, you can return a promise from your native method.

import com.facebook.react.bridge.Promise;

@ReactMethod
public void fetchDataFromNetwork(Promise promise) {
    try {
        // Perform network request
        String data = "Sample Data";
        promise.resolve(data);
    } catch (Exception e) {
        promise.reject("Error", e);
    }
}

In JavaScript, you can use async/await or then/catch to handle the promise returned by the native module.

MyCustomModule.fetchDataFromNetwork()
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error(error);
    });

Sending Events to JavaScript

Sometimes, you might need to send events from native code to JavaScript. This is useful for notifying JavaScript about changes or updates in the native environment. You can achieve this by using the RCTDeviceEventEmitter class.

import com.facebook.react.modules.core.DeviceEventManagerModule;

private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
    reactContext
        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit(eventName, params);
}

In JavaScript, you can listen for these events using the DeviceEventEmitter from react-native.

import { DeviceEventEmitter } from 'react-native';

DeviceEventEmitter.addListener('EventName', (event) => {
    console.log(event);
});

Conclusion

Creating custom native modules for Android in React Native provides a powerful way to extend the functionality of your applications. By leveraging native code, you can access platform-specific features and third-party libraries, enhancing the overall user experience. Understanding how to create and use native modules is an essential skill for any React Native developer aiming to build robust and feature-rich applications.

In this section, we've covered the steps to create a custom native module, handle asynchronous operations, and send events from native code to JavaScript. With this knowledge, you can confidently integrate native functionalities into your React Native projects, bridging the gap between JavaScript and native code.

Now answer the exercise about the content:

What is the primary purpose of creating custom native modules in React Native for Android applications?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image Using Native Modules for Extending React Native Features: Bridging JavaScript and Native Code

Next page of the Free Ebook:

15Using Native Modules for Extending React Native Features: Bridging JavaScript and Native Code

9 minutes

Obtenez votre certificat pour ce cours gratuitement ! en téléchargeant lapplication Cursa et en lisant lebook qui sy trouve. Disponible sur Google Play ou App Store !

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text