How to Integrating React-Native in existing app
- React Native setup in your system. If you don’t have then please follow this guide.
- So now we have two projects Native Android project and react-native project without any error
- 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
- 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
- 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
I really appreciate this post. I have been looking everywhere for this! Thank goodness I found it on Bing. You have made my day! Thx again
Thanks a lot 🙂