React NativeでAndroid向けにJavaを用いて、Native Modulesを実装する方法を解説します。
モグモグさん
出来るだけ分かりやすく解説していきます。
- Native Modulesがわかる
- Javaを用いてカスタムのNative Modulesを作成することができる
- React 17.0.2
- React Native 0.65.1
モグモグさん
Kotlinで実装する方法についてはこちらで解説しています。
【Android・Kotlin】React NativeでNative Modulesを実装する方法を解説
Native Modulesとは?
Native Modulesについて簡単に解説します。
モグモグさん
すでに理解している方はスキップしてください。
Native Modulesとは、React Nativeで用意されていない機能をネイティブで実装するための機能です。
アプリの要件によって、React Nativeがもともと用意していない機能を足したり、パフォーマンスの観点等でネイティブで実装すべき箇所をNative Modulesを使って実装したりすることが多いです。
React Nativeでも多くのことがすでにできますが、Native Modulesを使うことで幅が広がります。
- iOS: Objective-CとSwiftどちらでも実装可能
- Android: JavaとKotlinどちらでも実装可能
本記事では紹介しませんが、UIに関連するものは、Native UI Componentsを利用します。
モグモグさん
それぞれのドキュメントを貼っておきますので参考にしてください。
事前準備(ベースのアプリを作成)
まずは、React Nativeでアプリを作成しましょう。
この記事では、NativeModuleExampleというプロジェクトを作成しました。
モグモグさん
すでに作成済みの方はスキップでOKです!
こちらの記事も参考にしてください。
【ReactNative入門 】Macで開発環境を作って始める
Native Modulesの作成
それでは、Native Modulesを作成していきます。
CustomNativeModuleファイルの作成
android/app/src/main/java/com/your-app-name/
のフォルダにファイルを作成します。
本記事では、CustomNativeModuleJava
というファイル名にしましたが、任意の名前にしてください。
よく使いそうなメソッド + 具体的なメソッドを実装しています。
- シンプルなメソッド
- callbackを返すメソッド
- 引数を取るメソッド
- Promiseを扱うメソッド
- OSのバージョンを返すメソッド
モグモグさん
重要なポイントはコメントに記載しているので、確認してください。
メソッドは、@ReactMethod
をつけることで、JavaScript側から呼ぶことができます。
// ご自身のパッケージ名
package com.nativemoduleexample;
import android.os.Build;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
// ReactContextBaseJavaModuleを継承している点がポイント
public class CustomNativeModuleJava extends ReactContextBaseJavaModule {
public CustomNativeModuleJava(ReactApplicationContext reactContext) {
super(reactContext);
}
// getNameは必須で、JavaScriptから呼ぶ際のModule名になる
@Override
public String getName() {
return "CustomNativeModuleJava";
}
// 出力するだけのメソッド
@ReactMethod
public void funcSimple() {
System.out.print("funcSimple");
}
// callbackメソッド
@ReactMethod
public void funcCallback(Callback callback) {
callback.invoke("funcCallback");
}
// 引数を取るcallbackメソッド
@ReactMethod
public void funcCallbackWithParams(String param, Callback callback) {
callback.invoke("funcCallbackWithParams", param);
}
// Promise resolveパターンのメソッド
@ReactMethod
public void funcResolvePromise(Promise promise) {
promise.resolve("funcResolvePromise");
}
// Promise rejectパターンのメソッド
@ReactMethod
public void funcRejectPromise(Promise promise) {
promise.reject("error", "funcRejectPromise");
}
// 実用例: OSのバージョンを返すメソッド
@ReactMethod
public void getOSInfo(Callback callback) {
callback.invoke("android", Build.VERSION.RELEASE);
}
}
ReactPackageにModuleを追加
続いてReactPackageにModuleを追加します。
android/app/src/main/java/com/your-app-name/
のフォルダにファイルを作成します。
// ご自身のパッケージ名
package com.nativemoduleexample;
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;
// implements ReactPackageがポイント
public class CustomNativeModuleJavaPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
// 実装したmoduleを追加
modules.add(new CustomNativeModuleJava(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
MainApplicationにModuleを追加
続いて、MainApplication
にModuleを追加していきます。
変更点は、packages.add(new CustomNativeModuleJavaPackage());
の箇所です。
作成したmoduleを追加してください。
モグモグさん
変更点はここのみなので、全体のファイルは省略しています。
@Override
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 CustomNativeModuleJavaPackage());
return packages;
}
JavaScript側から使う
カスタムのNative Modulesを作成したので、JavaScript側から使う方法を解説していきます。
App.jsでimport
Moduleの名前は、ご自身で定義したものを使ってください。
import {NativeModules} from 'react-native';
const App = () => {
const {CustomNativeModuleJava} = NativeModules;
}
ch各メソッドを呼ぶ
呼ぶ場所は、任意ですが本記事では、useEffect
内でそれぞれのメソッドを呼んでみました。
const App = () => {
useEffect(() => {
CustomNativeModuleJava.getOSInfo((name, os) => {
console.log(name, os);
});
CustomNativeModuleJava.funcSimple();
CustomNativeModuleJava.funcCallback(result => {
console.log(result);
});
CustomNativeModuleJava.funcCallbackWithParams('test', (result, param) => {
console.log(result, param);
});
(async () => {
const result = await CustomNativeModuleJava.funcResolvePromise();
console.log(result);
})();
(async () => {
try {
await CustomNativeModuleJava.funcRejectPromise();
} catch (err) {
console.error(err);
}
})();
}, []);
}
実行結果
実装したModuleのメソッドがそれぞれ呼ばれていることが分かりますね。
まとめ
モグモグさん
お疲れ様でした!
Android向けにJavaを用いて、NativeModulesを実装する方法を解説しました。
React Nativeを実装する上で非常に有用なので、ぜひ実際に使ってみてください!