리액트 네이티브를 공부하면서 네이티브모듈을 사용해보고 싶어졌다.
사용하기 위해서 코틀린 설정을 해봐야하는데 너무 오래걸렸다. 기록기록
네이티브 모듈을 사용하려면 모듈 생성 -> 패키지 등록 순으로 이루어진다.
먼저 react native 사이트에 있는 setting 방법으로 react-native cli 를 이용해서 프로젝트를 생성해 준다.
안드로이드 스튜디오와 xcode 등 설벙은 공식 사이트를 참고했다.
https://reactnative.dev/docs/environment-setup
실행 환경은
MacOS m1
jdk 11
react-native 0.71 을 사용했다.
npx react-native init <프로젝트명>
으로 프로젝트를 생성해 준다.
1. android/build.gradle
먼저 생성된 프로젝트에서 android 디렉토리에 있는 build.gradle에 몇가지를 추가해준다.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
kotlinVersion = "1.7.0"
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
kotlinVersion을 1.7.0으로 해주고, dependencies에 classpath를 추가해준다.
2. android/app/build.gradle
다음으로는 adroid 안에 있는 app 안에 build.gradle 에 몇가지를 추가해준다.
apply plugin: "kotlin-android"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
}
2 코드를 각각 추가해 줬다.
3. module 생성
main/java/com/exam 디렉토리에 calculator 디렉토리를 만들고 CalculatorModule.kt파일을 추가해 줬다.
package com.exam.calculator
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Callback
class CalculatorModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName():String="CalculatorModule"
@ReactMethod
fun add(a:Double,b:Double,callback:Callback){
var c:Double = a+b
callback.invoke(c)
}
}
reactContext를 생성자 인자값으로 받고,ReactContextBaseJavaModul을 상속받는 CalculatorModule class를 만들어 줬다. getName() 메소드를 override 했다. getName은 react-native js 단에서 사용할 모듈 이름이다. 클래스 이름과 같이 지어줬다.
@ReactMethod 어노테이션을 달아주면, react-native 단에서 함수로 불러 사용할 수 있다.
add 메소드를 만들고 , Double 타입의 인자 a,b와 Callback 을 받아 준다.
a+b의 값을 가지는 c 변수를 callback의 invoke 메소드에 넣어준다.
만들어 둔 module을 react-native에서 사용하기 위해서는 다음으로 Package 묶어서 보내줘야한다고한다.
package com.exam.calculator
import android.view.View
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ReactShadowNode
import com.facebook.react.uimanager.ViewManager
class CalculatorPackage : ReactPackage {
override fun createViewManagers(
reactContext: ReactApplicationContext
): List<ViewManager<*,*>> = emptyList()
override fun createNativeModules(
reactContext: ReactApplicationContext
): MutableList<NativeModule> = listOf(CalculatorModule(reactContext)).toMutableList()
}
CalculatorPackage class 를 ReactPackage를 상속받아 만들어 주고 createViewManagers 와 createNativeModules를 override해서 정의 해준다. 만든 모듈은 createNativeModules에 들어 간다.
마지막으로 MainApplication.java 에서 패키지로 등록해준다.
package com.exam;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
import com.exam.calculator.CalculatorPackage;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@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 CalculatorPackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}
CalculatorPackage를 import 해주고 getPackages() 메소드안에 Package.add() 의 인자 값으로 new 로 생성해 넘겨준다.
이렇게 만들어진 모듈을 react-native에서 NativeModules를 먼저 import한뒤 NativeModules.모듈 로 사용할수 있다 .이때 모듈은 getName() 에서 정의해준 모듈 이름으로 사용가능하다.
import {NativeModules} from 'react-native';
const {CalculatorModule} = NativeModules;
CalculatorModule.add(1, 2, (sum: number) => {
console.log(sum);
});
그렇게 심도있게 알지는 못했지만 어쨌든 원하는 결과 값이 나온것에 우선 만족한다.
'project > Practice' 카테고리의 다른 글
[Flutter] stateful widget (0) | 2023.02.06 |
---|---|
[개발환경 설정]Practice #1 개발환경 설정 /springboot + react + mariadb (0) | 2023.02.06 |