It is a pleasant thing to develop a mobile app from scratch with React Native. However, for some products that have been launched, it is unrealistic to completely abandon the historical sediment of the original app and switch to React Native. Therefore, using React Native to unify the technology stack of Native Android and iOS apps as an extension module of existing Native apps is currently the most effective way to mix development. First, create a package.json file by executing the following command in the native Android project directory.

yarn init
Copy the code

Then, enter the corresponding configuration information as prompted. After the command is executed, you will notice that there is a package.json file in the root directory of the Android project. Next, use the following commands to add support scripts for the React and React Native runtime environments.

yarn add react react-native
Copy the code

After executing this command, you will find a node_modules folder in the root directory of the Android project, which contains the dependency modules needed to run the React Native development. In principle, this directory cannot be copied, moved, or modified. Next, use a text editor to open the package.json file and configure the React Native startup script as follows.

"scripts": {
    "start": "yarn react-native start",},Copy the code

At this point, the complete contents of the package.json file look like this.

{
  "name": "AndroidDemo"."version": "1.0.0"."main": "index.js"."license": "MIT"."dependencies": {
    "react": "^ 17.0.1"."react-native": "^ 0.63.4"
  },
  "scripts": {
    "start": "yarn react-native start"}}Copy the code

Then, create an index.js file in the root directory of your Android project. This file is the React Native entry file.

import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';

class HelloWorld extends React.Component {
    render() {
        return( <View style={styles.container}> <Text style={styles.hello}>Hello, React Native</Text> </View> ); }}const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
    },
    hello: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,}}); AppRegistry.registerComponent('MyReactNativeApp', () => HelloWorld);
Copy the code

Next, we use Android Studio to open the Native Android project and add React Native and JSC engine dependencies to the Dependencies code block in the build.gradle file in the app directory, as shown below.

dependencies {
    ...
    implementation "com.facebook.react:react-native:+" 
    implementation "org.webkit:android-jsc:+"
}
Copy the code

If the dependency version is not specified, the React Native version in the package.json file is used by default. Then, add the React Native and JSC engine paths to the AllProjects code block in the build.gradle file of your project, as shown below.

allprojects {
    repositories {
        maven {
            url "$rootDir/.. /node_modules/react-native/android"
        }
        maven {
            url("$rootDir/.. /node_modules/jsc-android/dist")}... }... }Copy the code

Then, open the androidmanifest.xml manifest file and add the network permission code, as shown below.

<uses-permission android:name="android.permission.INTERNET" />
Copy the code

To access the developer debug menu, you also need to register the DevSettingsActivity interface in the androidmanifest.xml manifest file, as shown below.

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
Copy the code

Next, create a new Activity as the React Native container page, create a ReactRootView object in the Activity, and launch the React Native application code within that object, as shown below.

public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {

    private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SoLoader.init(this.false);
        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder().setApplication(getApplication()).setCurrentActivity(this).setBundleAssetName("index.android.bundle").setJSMainModulePath("index").addPackage(new MainReactPackage()).setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build(a); mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);
        setContentView(mReactRootView);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager ! = null) { mReactInstanceManager.showDevOptionsDialog(a);return true;
        }
        return super.onKeyUp(keyCode, event); }}Copy the code

Missing statements can be imported automatically using Android Studio’s [Alt + Enter] shortcut, and BuildConfig is generated automatically at compile time without additional import. Because the React Native application debugging also requires the hover window permission, we need to add the hover window permission logic to the Android project code, as shown below.

private final int OVERLAY_PERMISSION_REQ_CODE = 1; 

private void requestPermission(a) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(! Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE); @}}}Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(! Settings.canDrawOverlays(this)) {
                // SYSTEM_ALERT_WINDOW permission not granted
            }
        }
    }
    mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
}
Copy the code

Next, we register MyReactActivity in the androidmanifest.xml manifest file, where we directly replace MainActivity with MyReactActivity as the main page of the application, as shown below.

<activity
      android:name=".MyReactActivity"
      android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>
Copy the code

After that, create an Assets folder in the SRC /main directory and execute the following packaging command.

react-native bundle --platform android --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --dev false
Copy the code

Then, run the yarn start command to start the React Native service and re-run the Native Android project to see the following figure.