Using React-Native just for UI development in Android App

React Native

This article describe how you can create your first android application using React Native

Here are steps by steps instruction to do that.

Setup the Android Environment

  • Setup Android Emulator(AVD) to run you application

3. Create a new Virtual Device

  • Now run your application, it would open up in the Android Emulator.
  • Now if you want to do coding in java, you can start using as it is. Android Studio provides all the features to build UI using xml. But if you are a web developer and more comfortable in Javascript and react, you can move to React-Native https://facebook.github.io/react-native/docs/getting-started.html.

Setup the React Native

  • Install react native cli
npm install -g react-native-cli
  • Create a react-native project
react-native init project-name
  • Start your emulator. you can start emulator using android studio or run the below command
~/Library/Android/sdk/tools/emulator @Nexus_5X_API_25

Nexus_5X_API_25: Name of my emulator

  • Run your react native application
react-native run-android
  • If you want to develop you application completely in javascript, thats all it is, But there are chances when there is some functionality you require is not in react-native modules. In that case you can build your own java modules. In order to do that you have to merge both these application: React native project and Android studio project.
  • We will discuss how we can communication between them.

Merge React Native and Android environment

  • Go to the react project directory
  • Delete the android folder
  • Now copy the project folder from the Android Studio project and move it to the react-native project directory with the folder name as “android”
  • Delete the “activity_main.xml” from the folder “android/app/src/main/res/layout”
  • Create a file “MyReactActivity”android/app/src/main/java/<package>/ and add the below content
import com.facebook.react.ReactActivity;

public class MyReactActivity extends ReactActivity {

/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "firstReact";
//this should be same as you have specified in "index.android.js" under AppRegistry.registerComponent
}
}
  • Create a file “MainApplication” android/app/src/main/java/<package>/ and add the below content
import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CustomReactPackage()
);
}
};

@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
  • Update your “AndroidManifest.xml” with the below data
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ankurkushwaha.eyespy"
>

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

<application
android:name=".MainApplication"
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=".MyReactActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />


</application>

</manifest>
  • In your app’s build.gradle file add the React Native dependency:
dependencies { 
compile “com.facebook.react:react-native:+” // From node_modules.
}
  • In your project’s build.gradle file add an entry for the local React Native maven directory. Be sure to add it to the "allprojects" block:
allprojects {     
repositories {
...
maven {
url "$rootDir/../node_modules/react-native/android" }
}
...
}

Configure HeadlessJS task

Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.

Its similar to creating an android service in java, just using it you can create service in javascript as well.

  • Register the js service using the below code
import {task} from './SomeTaskName';
AppRegistry.registerHeadlessTask('SomeTaskName', () => task);
  • Then, in SomeTaskName.js:
export async function task(taskData) {
    console.log('BACKGROUND AUDIO')
}
  • Create a service in your base package
public class MyTaskService extends HeadlessJsTaskService {
@Override
protected
@Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
   Log.d("MyTaskService", "task invoked in java");
   Bundle extras = intent.getExtras();
   return new HeadlessJsTaskConfig(
      "SomeTaskName",
      null,
      5000);
   }
}
// Register this service in AndroidManifest.xml 
// <service android:name=".MyTaskService"/>
  • Now if you start this service like any other service it will invoke the corresponding the javascript code. Here is the example for running inside the broadcast receiver.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();

context.startService(new Intent(context, MyTaskService.class));
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}

Communication between React Native and Native code

Now suppose you want to invoke a service or method defined in native code, in that case you need a mechanism to communicate b/w two. Here are the steps on how you can do that.

  • Create your CustomModule containing your method
public class ToastModule extends ReactContextBaseJavaModule {

private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";

public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}

@Override
public String getName() {
return "CustomToastAndroid";
}

@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
//this @ReactMethod will be available in javascript environment
@ReactMethod
public void show(String message, int duration) {
Log.d(getName(),"toast called with "+message);

//getReactApplicationContext().startService(new Intent(getReactApplicationContext(), MyTaskService.class));
//HeadlessJsTaskService.acquireWakeLockNow(getReactApplicationContext());
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}
  • Create a CustomReactPackage.java to register your module
public class CustomReactPackage implements ReactPackage {

@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {

List<NativeModule> modules = new ArrayList<>();

modules.add(new ToastModule(reactContext));

return modules;
}

}
  • Update your MainApplication file to include your CustomReactPackage
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CustomReactPackage() //custom package is added here
);
}
};
  • Here are the steps to use your custom module in ReactJS
import { NativeModules } from 'react-native';
ToastAndroid = NativeModules.CustomToastAndroid;

References

Like what you read? Give ankur kushwaha a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.