In today's episode we will use something from our Android code in our React Native app.
This might be something you would want: use something native in your app. How can we do that? It's not hard!
Luckly, React Native has an API to handle this. We can do this in three steps:
- Create our Native Module
- Register the module
- Wrap this module in the JavaScript code
Creating our Project
Let's create a React Native project that will use the native module.
react-native init UsingNativeModules
Ok! Project created!
Inside the React Native project, we have an Android project and a iOS project. We will use the Android project.
Creating our Native module
We will open the Android project using Android Studio.
The native functionality we will use is to keep the screen awake. This is something easy to implement in pure Java/Android code.
We start by creating a class and extending to
ReactContextBaseJavaModule
. Our module name will be
ViewUtil
. And I will call the class
ViewUtilModule
.
...
public class ViewUtilModule extends ReactContextBaseJavaModule {
...
In our module, we need to implement a method
called
getName
. This represents the class, which will be called in JavaScript. In our
case, our native module will be called
ViewUtl
. So, we can call this in
JavaScript by calling
React.NativeModules.ViewUtil
.
@Override
public String getName() {
return "ViewUtil";
}
Each method that will be visible in the JavaScript code should have a
@ReactMethod
annotation.
We will have two methods, one for keep the screen awake, and another to remove this. Let's have the reactContext as a field in the class, just in case we might want to use it in the future.
Now, let's create our two methods. To keep the screen awake, we need to get the current activity and add a flag to this activity by using WindowsManager. Keeping the screen awake means adding the
FLAG_KEEP_SCREEN_ON
, and removing that makes the screen just like normal.
...
public class ViewUtilModule extends ReactContextBaseJavaModule {
ReactApplicationContext reactContext;
public ViewUtilModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "ViewUtil";
}
@ReactMethod
public void keepScreenAwake() {
getCurrentActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
getCurrentActivity().getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
@ReactMethod
public void removeScreenAwake() {
getCurrentActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
getCurrentActivity().getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
Now, we have our two methods implemented.
Registering the module
Let's create anoter class that will implement the
ReactPackage
interface.
...
public class ViewUtilPackage implements ReactPackage {
...
We will call this
ViewUtilPackage
. Implemeting this interface means we need to implement two methods:
createNativeModules
and
createViewManagers
.
To register the module, we use the method
createNativeModules
.
With this, we will be able to call the methods from the Java code inside our JavaScript code.
Let's start by implementing this method. We will have a list of modules and we will add to this list the module we have created, the
ViewUtilModule
.
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new
ViewUtilModule(reactContext));
return modules;
}
For the
createViewManagers
method, we will just return an empty list for Collections.
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext
reactContext) {
return Collections.emptyList();
}
So, this will be the code for our React Package.
package com.usingnativemodules;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by franzejr on 10/5/17.
*/
public class ViewUtilPackage implements ReactPackage {
@Override
public List<NativeModule>
createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ViewUtilModule(reactContext));
return modules;
}
@Override
public List<ViewManager>
createViewManagers(ReactApplicationContext
reactContext) {
return Collections.emptyList();
}
}
We need add to this package to our
MainApplication.java
file, in the method
getPackages
. This file is also located inside our Android project.
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ViewUtilPackage()
);
}
};
This is everything we need to do on the Android side.
Using the Android code in our JavaScript project
Now we have implemented everything on the Android side. It's time to use this in our React Native project.
Let's create the file that gets our Android code.
vim ViewUtilModule.js
We will use
NativeModules
from
react-native
.
/**
* This exposes our Android code into our RN project
*/
import { NativeModules } from "react-native";
module.exports = NativeModules.ViewUtil;
And we can import this in any other file.
...
import ViewUtil from "./ViewUtilModule";
...
In our
componentDidMount
method, we will enable screenAwake.
componentDidMount() {
if (Platform.OS != "ios") {
ViewUtil.keepScreenAwake();
}
}
Take a look: here we are using the same method we declared in our Java code. Now, something from Java can be executed from here! Sweet!
Testing it
So, I have the app running. I've enabled live reload if we want to change something and see the changes quickly.
I've disabled the "Stay awake" options in the Developer options, and I set the time screen sleep to 15 seconds.
As you can see, this time I'm talking the screen is already off. We should open our app and the screen should be awake. Let's do that.
Ok, now our app is up. Let's count.. 1..2..3. Our screen should be up everytime. Yes. It seems it worked, nice! Now, we will disable the screenAwake, by using our method
removeScreenAwake
.
Ok, now, let's wait a couple seconds and see what happens with our screen. It should power off. Let's wait a bit more... Nice. It worked!
Summary
Today we saw how to create a native module in React Native using Android/Java code. As a native functionality we saw how to keep the screen awake.
Comments for Using Android Native Modules