Integrating React Native in existing Android app

How to Integrating React-Native in existing app

  1. React Native setup in your system. If you don’t have then please follow this guide.
  2. So now we have two projects Native Android project and react-native project without any error
  3. There are two types of integration you can integrate the react-native project in existing Native Android app as well as Native Android project in the existing Native Android app
  4. So let’s start, with integrate the react-native project in existing Android app

1. This is my Native Android folder structure

2. I have created a react-native project my folder structure is as follows

Integrating React-Native in existing app
Integrating React-Native in existing app
  • If you have an existing react-native project  then you can copy all selected folders as shown in the image and paste it in Android project otherwise Simply copy package.jsonfile in Native Android folder which shown below, you can also create this file manually

Package.json

{
  "name": "NativeApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
}
  • Now its time to install react-native packages in our project, So, open a terminal inside the root directory /NativeApp and run the following command.
npm install --save react@16.0.0-alpha.12 react-native

This command will create a new /node_modules folder inside the root directory. This folder contains all the javascript packages required to run the app.

3. Setting up the Android project

Open NativeApp in Android studio & configure maven by adding following dependency to /app/build.gradle file

compile "com.facebook.react:react-native:+"

 

Add an entry for the local React Native maven directory to build.gradle. Be sure to add it to the “allprojects” block and add it to NativeApp/build.gradle, not to NativeApp/app/build.gradle

maven {
url "<PATH TO YOUR ROOT DIRECTORY>/NativeApp/node_modules/react-native/android"
}

So, the NativeApp/build.gradle looks like this now.

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "D:/MyProjects2018/React-native/NativeApp/node_modules/react-native/android"
        }
    }
}

Then, Sync Android project

4. Add internet permission in AndroidManifest.xml

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

After adding AndroidManifest look like this

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.saurabhgite.nativeapp">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>

If you want to access DevSettingsActivity (used to access developer settings from the mobile app) then add it to AndroidManifest.xml

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

5. React-native index.js code

Now, time to add react Native code and create an activity in native Android which will render the React Native code. (index.js)Index.js is our entry file from the react-native project, if you don’t have index.js  then create index.js file inside the root directory /NativeApp and add these lines to it.

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

class HelloWorld extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.style}>Hello world</Text>
      </View>
    )
  }
}
var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  style: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});
AppRegistry.registerComponent('NativeApp', () => HelloWorld);

Make sure you write the same project name in AppRegistry.registerComponent() as written in package.json. i.e. ‘NativeApp’ If you are targeting Android API level ≥ 23 then you need to take a permission from the user for opening the React Native app from your native Android app, as after API level 23 new dynamic permission for opening other apps has been introduced. For requesting the permission add the following code either inside the onCreate() of the Main activity of the native app or inside the onCreate() of the activity which will open the React Native activity.

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);
    }
}

The override onActivityResult method to check permission result or simply add the following method in your activity

@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)) {
                Toast.makeText(this, "You have denied the permission, please accept permission and try again", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

I will suggest you add this code in MainActivity, it is better to get all permission at app start, so the code looks like as follows

6. Native Android MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int OVERLAY_PERMISSION_REQ_CODE = 1212;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        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)) {
                    Toast.makeText(this, "You have denied the permission, please accept permission and try again", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

Now, we will write the ReactActivity which will open the React Native App. So, create a new Activity ReactActivity using Android Studio and add the following code to it. 

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;

public class ReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "NativeApp", null);

        setContentView(mReactRootView);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
    }

    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }

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

}

Make sure all import is properly imported, make code error-free before moving forward you can import packages using Alt+Enter key

Also, change the theme of this activity as some of the components use this special theme. So, inside the AndroidManifest.xml update/add the following code.

<activity
  android:name=”.ReactActivity” 
  android:label=”@string/app_name”  
  android:theme=”@style/Theme.AppCompat.Light.NoActionBar”>
</activity>

Now simply Intent this ReactActivity like below

Intent intent = new Intent(this, ReactActivity.class);
startActivity(intent);

7. How to run the react-native project

case 1: If you integrate existing native Android studio app in react-native project then run following command

react-native run-android

case 2: If you integrate the existing react-native project in existing native Android app then this react-native run-android won’t be work it gets an error in this situation you simply run the project from Android studio because all react-native file is inside Android studio project so it will runs without errors

8. React-native code not getting update in Android studio

If you integrate the react-native project in the existing Android app Root folder like in case 2: and your .js file changes not reflecting in Android build then go to the root directory /NativeApp and run following command

react-native bundle --platform android --dev false --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res

this command will build your project and update index.android.bundle file in Android studio project, now simply run project all changes will reflect in build

 

2 Replies to “Integrating React Native in existing Android app”

Leave a Reply

Your email address will not be published.