React Native Integrating with an existing native app (Android)

In this article we will learn about how to integrate React-Native to an existing android app. This tutorial is made under the following environment

react-native-cli: 2.0.1
react-native: 0.50.3

As changing of version in react-native there me be some breaking changes but still flow of integration will be same.

Lets create a new react native project using react-native-cli,

react-native init myReactApp

then go to root project of your android app and create a folder named reactNativeSrc, (This is not monetary but it keep react native code isolated from native code)

Now add a package.json file into root of the native android project then add following lines

{
“name”: “myApp”,
“version”: “0.0.1”,
“private”: true,
“scripts”: {
“start”: “node node_modules/react-native/local-cli/cli.js start”
},
“dependencies”: {
“react”: “16.0.0”,
“react-native”: “0.50.4”
},
}

Then copy all of your react native project except ios , android and node_modules in to the reactNativeSrc directory.

Android File Structure

Note : android minimum sdk version ≥16

Now follow this steps :

Now open gradle.build which is located at project root directory myProj/build.gradle and in then all project block add following line.

allprojects {
repositories {

maven {
// All of React Native (JS, Android binaries) is installed from npm
url “$rootDir/node_modules/react-native/android”
}

}
}

Now open gradle.build which is located at project directory myProj/app/build.gradle and in then all project block add following line.

compile ‘com.android.support:appcompat-v7:23.0.1’
….
….
compile “com.facebook.react:react-native:+”

Now run gradle sync it should be run without any error now.

Now add a index.js file on to the root of the project directory then put the following code.

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

class HelloUser extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Hey! How are you?</Text>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});

AppRegistry.registerComponent('myApp', () => HelloUser);

Let’s do some native codding

Now create a activity select myapp.pacakeg→ file→ new→ javaclass
Name it MyReactActivityand add the following code.

package com.ranvir.applicationint;

import android.app.Activity;
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 MyReactActivity extends Activity 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, "myApp", 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();
}
}

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

}

Now add to Manifest.xml

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

Now add overlay permission check to the react native app add following code to MainActivity.java, It is necessary for development only.

package com.ranvir.applicationint;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Build;import android.provider.Settings;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import com.facebook.react.*;import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;import com.facebook.react.shell.MainReactPackage;public class MainActivity extends AppCompatActivity implements View.OnClickListener {

Button myButton; public static int OVERLAY_PERMISSION_REQ_CODE = 2; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myButton = (Button) findViewById(R.id.button); myButton.setOnClickListener(this); 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 public void onClick(View view) {
//Log.i("Test","Hello World"); Intent intent = new Intent(this, MyReactActivity.class); startActivity(intent); }

@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... }
}
}
}

}
Final output will look like this.

Some extra, you need to add a button to invoke react-native module onClick, after this when you click on this button it will open a new intent in native app.