React native android native module

Native Modules Intro

Sometimes a React Native app needs to access a native platform API that is not available by default in JavaScript, for example the native APIs to access Apple or Google Pay. Maybe you want to reuse some existing Objective-C, Swift, Java or C++ libraries without having to reimplement it in JavaScript, or write some high performance, multi-threaded code for things like image processing.

The NativeModule system exposes instances of Java/Objective-C/C++ (native) classes to JavaScript (JS) as JS objects, thereby allowing you to execute arbitrary native code from within JS. While we don’t expect this feature to be part of the usual development process, it is essential that it exists. If React Native doesn’t export a native API that your JS app needs you should be able to export it yourself!

Native Module Setup​

There are two ways to write a native module for your React Native application:

  1. Directly within your React Native application’s iOS/Android projects
  2. As a NPM package that can be installed as a dependency by your/other React Native applications

This guide will first walk you through implementing a native module directly within a React Native application. However the native module you build in the following guide can be distributed as an NPM package. Check out the Setting Up a Native Module as a NPM Package guide if you are interested in doing so.

Getting Started​

In the following sections we will walk you through guides on how to build a native module directly within a React Native application. As a prerequisite, you will need a React Native application to work within. You can follow the steps here to setup a React Native application if you do not already have one.

Imagine that you want to access the iOS/Android native calendar APIs from JavaScript within a React Native application in order to create calendar events. React Native does not expose a JavaScript API to communicate with the native calendar libraries. However, through native modules, you can write native code that communicates with native calendar APIs. Then you can invoke that native code through JavaScript in your React Native application.

In the following sections you will create such a Calendar native module for both Android and iOS.

Источник

Native Modules

Sometimes an app needs access to a platform API that React Native doesn’t have a corresponding module for yet. Maybe you want to reuse some existing Java code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.

We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don’t expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn’t support a native feature that you need, you should be able to build it yourself.

Native Module Setup​

Native modules are usually distributed as npm packages, apart from the typical javascript files and resources they will contain an Android library project. This project is (from NPM’s perspective) similar to any other media asset, meaning there isn’t anything unique about it from this point of view. To get the basic scaffolding make sure to read Native Modules Setup guide first.

Enable Gradle​

If you plan to make changes in Java code, we recommend enabling Gradle Daemon to speed up builds.

Читайте также:  Разделить экран 2 части андроид

The Toast Module​

This guide will use the Toast example. Let’s say we would like to be able to create a toast message from JavaScript.

We start by creating a native module. A native module is a Java class that usually extends the ReactContextBaseJavaModule class and implements the functionality required by the JavaScript. Our goal here is to be able to write ToastExample.show(‘Awesome’, ToastExample.SHORT); from JavaScript to display a short toast on the screen.

Create a new Java Class named ToastModule.java inside android/app/src/main/java/com/your-app-name/ folder with the content below:

ReactContextBaseJavaModule requires that a method called getName is implemented. The purpose of this method is to return the string name of the NativeModule which represents this class in JavaScript. So here we will call this ToastExample so that we can access it through React.NativeModules.ToastExample in JavaScript.

An optional method called getConstants returns the constant values exposed to JavaScript. Its implementation is not required but is very useful to key pre-defined values that need to be communicated from JavaScript to Java in sync.

To expose a method to JavaScript a Java method must be annotated using @ReactMethod . The return type of bridge methods is always void . React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).

Argument Types​

The following argument types are supported for methods annotated with @ReactMethod and they directly map to their JavaScript equivalents

Register the Module​

The last step within Java is to register the Module; this happens in the createNativeModules of your apps package. If a module is not registered it will not be available from JavaScript.

create a new Java Class named CustomToastPackage.java inside android/app/src/main/java/com/your-app-name/ folder with the content below:

The package needs to be provided in the getPackages method of the MainApplication.java file. This file exists under the android folder in your react-native application directory. The path to this file is: android/app/src/main/java/com/your-app-name/MainApplication.java .

To access your new functionality from JavaScript, it is common to wrap the native module in a JavaScript module. This is not necessary but saves the consumers of your library the need to pull it off of NativeModules each time. This JavaScript file also becomes a good location for you to add any JavaScript side functionality.

Create a new JavaScript file named ToastExample.js with the content below:

Now, from your other JavaScript file you can call the method like this:

Please make sure this JavaScript is in the same hierarchy as ToastExample.js .

Beyond Toasts​

Callbacks​

Native modules also support a unique kind of argument — a callback. In most cases it is used to provide the function call result to JavaScript.

This method would be accessed in JavaScript using:

A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later.

It is very important to highlight that the callback is not invoked immediately after the native function completes — remember that bridge communication is asynchronous, and this too is tied to the run loop.

Promises​

Native modules can also fulfill a promise, which can simplify your JavaScript, especially when using ES2016’s async/await syntax. When the last parameter of a bridged native method is a Promise , its corresponding JS method will return a JS Promise object.

Refactoring the above code to use a promise instead of callbacks looks like this:

The JavaScript counterpart of this method returns a Promise. This means you can use the await keyword within an async function to call it and wait for its result:

Threading​

Native modules should not have any assumptions about what thread they are being called on, as the current assignment is subject to change in the future. If a blocking call is required, the heavy work should be dispatched to an internally managed worker thread, and any callbacks distributed from there.

Sending Events to JavaScript​

Native modules can signal events to JavaScript without being invoked directly. The easiest way to do this is to use the RCTDeviceEventEmitter which can be obtained from the ReactContext as in the code snippet below.

Читайте также:  Android adb check device

JavaScript modules can then register to receive events by addListener on the NativeEventEmitter class.

Getting activity result from startActivityForResult ​

You’ll need to listen to onActivityResult if you want to get results from an activity you started with startActivityForResult . To do this, you must extend BaseActivityEventListener or implement ActivityEventListener . The former is preferred as it is more resilient to API changes. Then, you need to register the listener in the module’s constructor,

Now you can listen to onActivityResult by implementing the following method:

We will implement a basic image picker to demonstrate this. The image picker will expose the method pickImage to JavaScript, which will return the path of the image when called.

Listening to LifeCycle events​

Listening to the activity’s LifeCycle events such as onResume , onPause etc. is very similar to how we implemented ActivityEventListener . The module must implement LifecycleEventListener . Then, you need to register a listener in the module’s constructor,

Now you can listen to the activity’s LifeCycle events by implementing the following methods:

Источник

Создаем нативный Android модуль и связываем его с React Native приложением.

В этой статье мы создадим нативный Android модуль, который будет возвращать уровень заряда батарейки смартфона в React Native приложение.

Но для начала я советую прочитать не большую статью о том, как работает React Native.

Создаем нативный Android модуль

Готовим основной файл модуля

Открываем проект на React Native и ищем в нем папку
android/app/src/main/java/com/[название вашего проекта]/.

Создаем в ней файл BatteryLevel.java.

Мы только что создали каркас для нашего модуля. В этом файле мы будем описывать методы, которые хотим использовать из JavaScript.

Для того, чтобы мы смогли обратиться к модулю из JavaScript, нужно добавить обязательный метод getName и указать в нем имя нашего модуля.

Пока что модуль не умеет определять уровень заряда батарейки.

Поэтому нужно написать метод getLevel, который определит уровень заряда и передаст его в JavaScript.

Хочу заострить ваше внимание на некоторых вещах:

  1. Аннотация @ReactMethod перед методом говорит, что мы можем вызвать этот метод из JavaScript. Это обязательное условие, иначе вы не сможете вызвать этот метод из JavaScript.
  2. Методы, которые мы хотим вызвать из JavaScript, должны иметь возвращаемый тип void. Это значит, что метод ничего не возвращает явным образом, т.е. нет оператора return в конце метода.

Раз метод ничего не возвращает, то как он передаст значение заряда батарейки в JavaScript?

Для этого мы используем callback-метод. Из JavaScript файла мы передадим в метод getLevel функцию, которая должна быть выполнена по его окончании. В нашем случае это updateLevelCallback.

Регистрируем модуль

Основная часть модуля готова. Теперь нам нужно зарегистрировать его, чтобы он стал доступен из JavaScript.

Для этого создадим файл-пакет BatteryLevelPackage.java в папке android/app/src/main/java/com/[название вашего проекта]/ и добавим модуль в метод createNativeModules.

Добавляем пакет модуля ко остальным пакетам приложения

Пакет модуля должен быть предоставлен в методе getPackages в файле MainApplication.java. В этом методе через запятую указываются все пакеты нативных модулей, используемых в React Native проекте.

Используем нативный Android модуль в React Native приложении

В проекте React Native в файле App.js (вы можете использовать любой другой файл) импортируем NativeModules из пакета ‘react-native’ и достаем из него недавно созданный модуль BatteryLevel.

Полный код файла App.js

По нажатию на кнопку «Показать уровень заряда», мы вызываем метод getLevel из нативного модуля BatteryLevel и передаем в него функцию с аргументом batteryLevel. Нативный модуль вернет нам значение batteryLevel.

Подытожим

Шаги для создания и использования нативного Android модуля в React Native приложении:

  1. Создаем основной файл модуля в папке android/app/src/main/java/com/[название вашего проекта]/.
  2. Создаем пакет модуля в той же папке и регистрируем модуль.
  3. Добавляем пакет модуля в метод getPackages в файле MainApplication.java.
  4. В React Native проекте в файле App.js (или в другом) импортируем NativeModules из пакета ‘react-native’.
  5. Используем нативный модуль: NativeModules.[имя модуля].[имя метода]().

Задавайте вопросы, указывайте на неточности и делитесь своим опытом в комментариях.

Источник

How to use Native Modules in React Native + Android — Hybrid Apps

Well, when you are developing hybrid apps (React Native for some modules and native android for rest of the module) then you must have came up with this situation that How can I use the native android functionality / classes like SharedPreference or Utilities class etc ?

Читайте также:  Как открыть php файл андроид

Well, It is really simple with Native Module. You can write your own app specific Native Modules. In this blog we will learn how to create one. For this blog our aim would be to access SharedPreference of Native Android app.

Before getting started please make sure that you have the following setup ready in your computer.
1. Android Studio
2. React Native setup
3. An existing hybrid (React Native + Android) project

If you have existing project only in native Android then follow this blog to setup the React Native.

Integrating React Native with existing Android app

In your Android Studio, create a new Java file SharedPrefereneModule.java at your convenient path and extend it with ReactContextBaseJavaModule . There is a one abstract method getName() of this super class which you need to override. This method returns name of the module by which you can access it from React Native. Also, you need a constructor with React Application Context.

Here, we have also created an instance of AppSharedPreferenceManager (a class which handles shared preferences) which we will need in next steps.

Note: If you don’t want to do SharedPreference operations in other class then you can simply create SharedPreference instance instead here of AppSharedPreferenceManager.

Now we need packager to provide this module to React Instance Manager, so Create a new java file SharedPreferencePackager.java at your convenient path and extend it with ReactPackage . This class has three abstract methods which we need to override. See the following code for it.

Here, we have added SharedPrefereneModule which we created in first step to Native Module list. This packager can also be used for Native Ui Components and JS modules, but in this blog we are only focusing on Native Modules so we are returning empty list in other two methods.

Step 3 : Add package to React Instance Manager

As we have created the SharePreferencePackager now we are ready to add it in React Instance Manager. To do so open your ReactActivity and find the reactInstanceManager initialization and add SharePreferencePackager.

This react instance manager you won’t be able to find if you have created project using react-native init . In that case you need to add this package inside getPackages() method.

Step 4: Add methods and usage

Now we are ready with the Native Module. We need to create methods which can read and write the SharedPreference of native android. So open the SharedPreferenceModule.java created in step 1. Add the methods required for your application with a @ReactMethod annotation. Here is a one sample method.

You must be worried about two thing in the above method.
1. Return type is void
2. What the hack is Callback?

So, one thing you need to understand is that you are calling this methods from React Native so you cannot simply return anything just by changing the return type from void to something like String or int or boolean. For the native Android to React Native communication the Callbacks are used. Callback is nothing but javascript callbacks just like onTextChange of

tag. You can accept as many callbacks as you want in this method (like successCallback, failureCallback etc.). When you have data you can invoke the callback and the rest will be handled by JS.

Here is the code snippet in React Native to use the created Native Module. As you see here we are passing one callback. When we have mpin ready at Java side we will invoke the callback and the JS console will print this mpin.

If you like this blog please click on heart ❤ to support me for reaching as many people as I can. In case of any queries you can comment below or drop an email on rajsuvariya@gmail.com.

Next, I will be writing blog on using Android Native views inside React Native. Follow me and stay tuned.

#ReactNative #Android #NativeModules #HybridApps

Источник

Оцените статью