Reputation: 850
I'd like to import a module written natively (java, Android) into my React Native sources, in JS.
Upvotes: 0
Views: 769
Reputation: 238
To access your functionality implemented in java you have to create a bridge. You can see the most recent instructions in the RN documentation site*.
The steps, assuming React Native 0.61, for a hello world, to be implemented in the android project inside the react native app directory (android directory): 1) First you create a simple POJO class to be returned to the react native context:
class MyData{
private int timeSpentSleeping;
public int getTimeSpentSleeping() {
return timeSpentSleeping;
}
public void setTimeSpentSleeping(int timeSpentSleeping) {
this.timeSpentSleeping = timeSpentSleeping;
}
@NonNull
@Override
public String toString() {
Gson gson = new Gson();
String json = gson.toJson(this);
return json;
}
static MyData build(final int timeSpentSleeping){
MyData newInstance = new MyData();
newInstance.timeSpentSleeping = timeSpentSleeping;
return newInstance;
}
}
And the react native module that do something and return objects of this class as javascript Promises:
public class HelloPromiseModule extends ReactContextBaseJavaModule {
public HelloPromiseModule(@NonNull ReactApplicationContext reactContext) {
super(reactContext);
}
@NonNull
@Override
public String getName() {
return "HelloPromise";
}
@ReactMethod
public void foobar(Promise promise){
Random r = new Random();
final int timeToSleep = r.nextInt(1000);
runThreadAndCallPromiseToJavascript(timeToSleep, promise);
}
//Cria um thread pra executar algo em paralelo
private void runThreadAndCallPromiseToJavascript(final int timeToSleep,final Promise promise){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(timeToSleep);
MyData result = MyData.build(timeToSleep);
promise.resolve(result.toString());
} catch (InterruptedException e) {
e.printStackTrace();
promise.reject(e);
}
}
});
t.run();
}
}
Now, we create the React Native Package (that is different from java packages):
public class HelloWorldPackage implements ReactPackage{
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new HelloPromiseModule(reactContext));
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
The last step in the android version of your react native app is to register your HelloWorldPackage: In the MainApplication.java inside your android project, inside the getPackages(), in the list of packages (new PackageList(this)...):
packages.add(new HelloWorldPackage());
Something like that:
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new HelloWorldPackage());
return packages;
}
Now, to get your native class in the javascript world:
import {
NativeModules,
} from 'react-native';
...
const {HelloPromise} = NativeModules;
Your native class is accessible from the variable HelloPromise. You can get the result of HelloPromise.foobar() with something like this, in the react native side of your code:
async function handleHelloPromisesPress() {
let result = await HelloPromise.foobar();
console.log(result);
}
You may notice that 'result' is a json whose structure is equal to the POJO class we created in the beginning.
Upvotes: 1