[JAVA] How to write React Native bridge ~ Android version ~

I want to use native functions with React Native! Isn't there a time? However, there is no third party I'm looking for from GitHub. It's full of bugs and not maintained. And so on, the native side must also write. A situation like this occurs.

I would like to share a method to bridge native functions to React (js) side, which is useful in such a case.

TL;DR

--Https://github.com/react-native-community/react-native-camera is the subject --Create a module class that uses Android functions directly --Create a package class that implements the ReactPackage interface to handle the created module on the React side.

When using Android's Native function, there are functions without View such as voice and background processing, and functions with View such as camera preview.

Since the method of passing the value to React differs depending on whether there is a View or not, we will consider it separately here.

common part

Implement a class that implements the ReactPackage interface

  1. Register NativeModule that provides functions other than view for use on React side
  2. Register viewManager to use UI Component provided by Native on React side
  3. createJSModules is not currently required

RNCameraPackage.java


package ...

import ...

public class RNCameraPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
        return Arrays.<NativeModule>asList(
                new RCTCameraModule(reactApplicationContext),
                new CameraModule(reactApplicationContext),
                new FaceDetectorModule(reactApplicationContext)
        );
    }

    // Deprecated in RN 0.47
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
        return Arrays.<ViewManager>asList(
                new RCTCameraViewManager(),
                new CameraViewManager()
        );
    }
}

If you want to bridge Native functions other than UI

Implement a module that inherits ReactContextBaseJavaModule
  1. In the java file on the android / app / src side, create a class that inherits the ReactContextBaseJavaModule class.

  2. Write the Module name

  3. Define constants to be used on React side (without it)

  4. Define the method to be used on React side. At this time, @ReactMethod annotation is added.

CameraModule.java


//① 
public class CameraModule extends ReactContextBaseJavaModule {
    private static final String TAG = "CameraModule";

    ...

    public CameraModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mScopedContext = new ScopedContext(reactContext);
    }

    ...

    //②
    @Override
    public String getName() {
        return "RNCameraModule";
    }

    //③
    @Override
    public Map<String, Object> getConstants() {
        return Collections.unmodifiableMap(new HashMap<String, Object>() {
            {
                put("Type", getTypeConstants());
                put("FlashMode", getFlashModeConstants());
                ...
            }
        });
    }

    ...

    //④
    @ReactMethod
    public void takePicture(final ReadableMap options, final int viewTag, final Promise promise) {
        final ReactApplicationContext context = getReactApplicationContext();
        final File cacheDirectory = mScopedContext.getCacheDirectory();
        UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
        uiManager.addUIBlock(new UIBlock() {
        @Override
        public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
            RNCameraView cameraView = (RNCameraView) nativeViewHierarchyManager.resolveView(viewTag);
                try {
                    if (cameraView.isCameraOpened()) {
                        cameraView.takePicture(options, promise, cacheDirectory);
                    } else {
                        promise.reject("E_CAMERA_UNAVAILABLE", "Camera is not running");
                    }
                } catch (Exception e) {
                  promise.reject("E_CAMERA_BAD_VIEWTAG", "takePictureAsync: Expected a Camera component");
                }
            }
        });
    }

    ...

}
When writing ReactMethod, if there is an argument from JS and the type is Object or Array
Object => ReadableMap
Array => ReadableArray

Replace the type with and use the argument. Also, use for all arguments handled by ReactMethod.

If you want to bridge UI-based Native functions

  1. Import com.facebook.react.uimanager.ViewGroupManager
  2. Create a class that inherits ViewGroupManager
  3. Override getName () to determine the Module name
  4. createViewInstanceOverride to describe the UI Component you want to use and create a method that returns that component

CameraViewManager.java


package com.example;

//①
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;

//②
public class CameraViewManager extends ViewGroupManager<RNCameraView> {
    private static final String REACT_CLASS = "RNCamera";

    @Override
    public void onDropViewInstance(RNCameraView view) {
        view.stop();
        super.onDropViewInstance(view);
    }

    //③
    // Component name that will be called from JavaScript
    @Override
    public String getName() {
        return REACT_CLASS;
    }

    //④
    // Return the view component instantiated with Activity context
    @Override
    public TextView createViewInstance(ThemedReactContext reactContext) {
        return new RNCameraView(themedReactContext);
    }
}

Use Native Module on JS side

  1. Call NativeModule. {Value returned by getName ()}. (Here, export with RNCamera.js so that it can be used as a separate file.

OriginalCamera.js


import { NativeModules } from `react-native`;

export default NativeModules.RNCameraModule;

Recommended Posts

How to write React Native bridge ~ Android version ~
How to make Unity Native Plugin (Android version)
Using Native UI Component with React Native (Android version)
How to write dockerfile
How to write docker-compose
How to write Mockito
How to write migrationfile
How to lower java version
How to write good code
Bit Tetris (how to write)
How to write java comments
[Refactoring] How to write routing
Great poor (how to write)
[Note] How to write Dockerfile/docker-compose.yml
How to write Junit 5 organized
How to write Rails seed
[Ruby] How to write blocks
How to check JSF version
How to write Rails routing
[2020 version] How to send an email using Android Studio Javamail
Studying Java # 6 (How to write blocks)
How to "hollow" View on Android
[Rails] How to write in Japanese
[React Native] Write Native Module in Swift
Baseball ball count (how to write)
How to write a ternary operator
Rails on Tiles (how to write)
[Rails] How to write exception handling?
How to write Java variable declaration
Y-shaped road tour (how to write)
How to write easy-to-understand code [Summary 3]
[RSpec] How to write test code
[Android] How to make Dialog Fragment
Android: How to deal with "Could not determine java version from '10 .0.1'"
[Basic] How to write a Dockerfile Self-learning ②
How to detect microphone conflicts on Android
Summary of how to write annotation arguments
[Java] How to output and write files!
How to install the legacy version [Java]
How to write Spring AOP pointcut specifier
How to write an RSpec controller test
How to add application version information to Sentry information
[SpringBoot] How to write a controller test
How to write and explain Dockerfile, docker-compose
How to use ExpandableListView in Android Studio
Rails: How to write a rake task nicely
[JavaFX] How to write Eclipse permissions in build.gradle
How to write offline 15th reference question answer
[Rails] How to write when making a subquery
[Android] How to convert a character string to resourceId
Java Development Basics ~ How to Write Programs * Exercise 1 ~
How to write an if statement to improve readability-java
[Android] How to detect volume change (= volume button press)
JUnit 5: How to write test cases in enum
Offline real-time how to write F06 implementation example
How to write code that thinks object-oriented Ruby
How to write test code with Basic authentication
How to use nfs protocol version 2 with ubuntu 18.04
[Java] Memo on how to write the source
How to write Java String # getBytes in Kotlin?
How to run NullpoMino 7.5.0 on Ubuntu 20.04.1 64bit version