React Native from the Android dev’s point of view (part I)

Irina Galata
ProAndroidDev
Published in
5 min readApr 21, 2017

--

React Native has become quite popular among mobile developers and I couldn’t resist the urge to get acquainted with this framework to keep pace with the new trends in app development. It was important to see if I could use it in production effectively.

Reviewing the project structure

Let’s get started! After everything is setup, you can create a project by entering a single command in the terminal:

react-native init TestProject
Generated project structure

The structure of the generated project is pretty straightforward. It contains the well-known Android project, which you could open in Android Studio, and the iOS project, which also is acceptable by Xcode. There it’s possible to develop platform-specific parts of the application. But the main part of the future logic will be placed outside them. The node_modules directory contains all of the included dependencies. index.android.js is the entry point for the Android app, while the index.ios.js is the same thing for the iOS application.

Let’s choose an IDE

One of the most important questions when you’re starting to use a new programming language is the choice of the editor for development.

The first option is to use Atom, a quite beautiful and easily customizable text editor. It’s hard to compare it with Android Studio, but it worth giving it a chance. Also you could find it useful to install Deco IDE. It seems to be more functional than the previous one and includes a graphical editor, which could ease the building of the UI. Here you can find some other options for you.

For now my choice is Vim — a highly-customizable, time-tested and lightweight editor.

Vim editor

What about UI?

Poor UI and lack of native functionality support are common problems of the majority of tools for crossplatform development . The reason for this is the use of HTML and CSS for rendering. But React Native takes a quite different approach — it renders using native components. And as a result it’s hard to find out the difference between the app written in Java or Kotlin and React Native app.

Let’s see how such an app looks.

In the example above the code is the same for Android and iOS, but it’s a common case to have separate files for more difficult screens, that slightly differ for each platform. As a result one development team can work with two different platforms using the same approach.

The screen looks native on Android and iOS at the same time, and so it is. I’ve used nativebase.io library for this purpose. It makes the UI creating even easier.

The code above written in JSX — an XML-like language. Its tags have tag names, attributes and children just like the ones in XML. There is nothing complicated about this, is there?

Java and Kotlin code interoperability

The question I cared about is the reuse of the libraries written earlier in Java or Kotlin. It would be a pity if they were useless for apps developed in React Native. Luckily it’s possible to use them as native modules. They are used to implement any platform-specific functionality in the project.

Let’s imagine, that you need to open the camera preview, without any of existing solution for that (for some reason) and write it in Kotlin.

The first step is to create the module to implement the needed functionality — to open camera in our case. Here you can use Android Studio to edit the android part of the project.

I’ve created a CameraModule, which extends ReactContextBaseJavaModule class in order to make it acceptable by our React Native project. It’s necessary to implement the getName() function to be able to access the module later. And now it’s time to actually create a function to open a camera preview. The only requirement is to add a @ReactMethod annotation so it can be visible from JavaScript file.

Now you need to create a descendant of the ReactPackage interface to add the CameraModule into it. Now we’re only interested in the createNativeModules() function. Here I return a list containing the needed module.

The only thing left is to add this package to the list of packages in the MainApplication class (no need to create it, it already exists in the android package).

And now that it’s ready, let’s import the created module to the index.android.js file and actually show the camera.

import { NativeModules } from 'react-native';
const camera = NativeModules.CameraModule;

To add a listener for a button, I use the onPress attribute:

<Button onPress={()=>camera.openCamera}/>

How to get the photo uri back in the js file? First, it’s necessary to implement ActivityEventListener and pass its descendant to the reactApplicationContext.addActivityEventListener() function in the constructor of the module. Let’s review the updated CameraModule:

onActivityResult() and onNewIntent() are the only functions of the interface.

Let’s update the openCamera() function call:

To review logs from the device use these commands:

react-native log-androidreact-native log-ios

The last but not least — existing solutions

Sometimes you face an issue, which you can’t resolve in a quick and easy way. And if you develop applications using React Native you’ll certainly be in a similar situation.

But luckily there are plenty of small and huge JavaScript libraries which could help you in any situation. Most of them could be easily installed in your project using the npm package manager. Just use the command below and start using a new functionality:

npm install <library_name>

You can discover all of them here.

--

--