React NativeでAndroid向けにKotlinを用いて、Native Modulesを実装する方法を解説します。
モグモグさん
出来るだけ分かりやすく解説していきます。
- Native Modulesがわかる
- Kotlinを用いてカスタムのNative Modulesを作成することができる
- React 17.0.2
- React Native 0.65.1
モグモグさん
Javaで実装する方法についてはこちらで解説しています。
【Android・Java】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で開発環境を作って始める
Kotlinを動かす
まずは、React NativeでKotlinを動かす方法を解説します。
build.gradle
にkotlin-gradle-plugin
を追加
モグモグさん
app/
の外のbuild.gradle
に追加します。
変更点のある箇所だけ記載しています。
buildscript {
ext {
kotlin_version = '1.5.20'
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
app/
内のbuild.gradle
を更新
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
動作確認
モグモグさん
Kotlinが動作するようになったので、動作確認をして問題なくビルドができるか確認しましょう。
Native Modulesの作成
それでは、Native Modulesを作成していきます。
CustomNativeModuleファイルの作成
android/app/src/main/java/com/your-app-name/
のフォルダにファイルを作成します。
本記事では、CustomNativeModuleKotlin
というファイル名にしましたが、任意の名前にしてください。
よく使いそうなメソッド + 具体的なメソッドを実装しています。
- シンプルなメソッド
- callbackを返すメソッド
- 引数を取るメソッド
- Promiseを扱うメソッド
- OSのバージョンを返すメソッド
モグモグさん
重要なポイントはコメントに記載しているので、確認してください。
メソッドは、@ReactMethod
をつけることで、JavaScript側から呼ぶことができます。
// ご自身のパッケージ名
package com.nativemoduleexample
import android.os.Build
import com.facebook.react.bridge.*
// ReactContextBaseJavaModuleを継承している点がポイント
class CustomNativeModuleKotlin(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
// getNameは必須で、JavaScriptから呼ぶ際のModule名になる
override fun getName(): String {
return "CustomNativeModuleKotlin"
}
// 出力するだけのメソッド
@ReactMethod
fun funcSimple() {
print("funcSimple")
}
// callbackメソッド
@ReactMethod
fun funcCallback(callback: Callback) {
callback.invoke("funcCallback")
}
// 引数を取るcallbackメソッド
@ReactMethod
fun funcCallbackWithParams(param: String?, callback: Callback) {
callback.invoke("funcCallbackWithParams", param)
}
// Promise resolveパターンのメソッド
@ReactMethod
fun funcResolvePromise(promise: Promise) {
promise.resolve("funcResolvePromise")
}
// Promise rejectパターンのメソッド
@ReactMethod
fun funcRejectPromise(promise: Promise) {
promise.reject("error", "funcRejectPromise")
}
// 実用例: OSのバージョンを返すメソッド
@ReactMethod
fun 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
class Main : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
override fun createNativeModules(
reactContext: ReactApplicationContext): List<NativeModule> {
val modules = ArrayList<NativeModule>()
// moduleを追加
modules.add(CustomNativeModuleKotlin(reactContext))
return modules
}
}
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 Main());
return packages;
}
JavaScript側から使う
カスタムのNative Modulesを作成したので、JavaScript側から使う方法を解説していきます。
App.jsでimport
Moduleの名前は、ご自身で定義したものを使ってください。
import {NativeModules} from 'react-native';
const App = () => {
const {CustomNativeModuleKotlin} = NativeModules;
}
各メソッドを呼ぶ
呼ぶ場所は、任意ですが本記事では、useEffect
内でそれぞれのメソッドを呼んでみました。
const App = () => {
useEffect(() => {
CustomNativeModuleKotlin.getOSInfo((name, os) => {
console.log(name, os);
});
CustomNativeModuleKotlin.funcSimple();
CustomNativeModuleKotlin.funcCallback(result => {
console.log(result);
});
CustomNativeModuleKotlin.funcCallbackWithParams('test', (result, param) => {
console.log(result, param);
});
(async () => {
const result = await CustomNativeModuleKotlin.funcResolvePromise();
console.log(result);
})();
(async () => {
try {
await CustomNativeModuleKotlin.funcRejectPromise();
} catch (err) {
console.error(err);
}
})();
}, []);
}
実行結果
実装したModuleのメソッドがそれぞれ呼ばれていることが分かりますね。
まとめ
モグモグさん
お疲れ様でした!
Android向けにKotlinを用いて、Native Modulesを実装する方法を解説しました。
React Nativeを実装する上で非常に有用なので、ぜひ実際に使ってみてください!