본문 바로가기
개발/ReactNative

ReactNative_ AOS 커스텀 RCTEmitter 생성 및 적용

by JunsC 2024. 3. 5.
728x90

 

🚀 React Native에서 AOS(Custom RCTEmitter) 생성하기

React Native에서 AOS(Android)용 커스텀 이벤트 모듈을 생성할 때 RCTEventEmitter를 활용하면 네이티브(Android) ↔ JavaScript 간 이벤트 기반 통신이 가능해!
예를 들어, 네이티브에서 발생하는 이벤트(예: 센서 값 변화, 네트워크 상태 변화 등)를 JS로 전달할 때 유용해.

 

 

🟢 1. RCTEventEmitter란?

RCTEventEmitter는 React Native에서 네이티브(Android) → JavaScript로 이벤트를 전달하는 인터페이스야.
Android(Java/Kotlin)에서 이벤트를 발생시키고, JS에서는 DeviceEventEmitter를 통해 이를 구독(subscribe)할 수 있어.

사용 예시:

  • 네이티브 센서 값 변화를 JS에서 실시간으로 받기
  • 네이티브 네트워크 상태 변경을 JS에서 감지
  • 커스텀 네이티브 기능 실행 후 JS로 결과 전달

 

 

🔵 2. Android 커스텀 RCTEventEmitter 구현하기

1) 네이티브 모듈 생성 (MyCustomEventModule.java)

먼저, MyCustomEventModule을 생성해서 React Native와 연동할 네이티브 모듈을 만든다.

 

package com.yourapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;

public class MyCustomEventModule extends ReactContextBaseJavaModule {
    
    private static ReactApplicationContext reactContext;

    public MyCustomEventModule(ReactApplicationContext context) {
        super(context);
        reactContext = context;
    }

    @Override
    public String getName() {
        return "MyCustomEventModule";  // JS에서 호출할 네이티브 모듈 이름
    }

    // 이벤트를 JS로 전송하는 함수
    private void sendEvent(String eventName, WritableMap params) {
        if (reactContext.hasActiveCatalystInstance()) {
            reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit(eventName, params);
        }
    }

    // 네이티브에서 호출하는 메서드 (예제: 이벤트 발생)
    @ReactMethod
    public void triggerEvent(String message) {
        WritableMap params = new WritableNativeMap();
        params.putString("message", message);

        sendEvent("CustomEvent", params);  // "CustomEvent"라는 이름으로 이벤트 전송
    }
}
 

📌 설명

✔ ReactContextBaseJavaModule → React Native와 연결할 네이티브 모듈 생성
✔ getName() → JavaScript에서 접근할 때 사용할 모듈명 (MyCustomEventModule)
✔ sendEvent() → 네이티브에서 발생한 이벤트를 JS로 전달
✔ triggerEvent() → JS에서 직접 네이티브 이벤트를 실행하는 메서드

 

 

2) 네이티브 모듈 패키지 등록 (MyCustomEventPackage.java)

package com.yourapp;

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;

public class MyCustomEventPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new MyCustomEventModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager<?, ?>> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

📌 설명

✔ ReactPackage → React Native에서 네이티브 모듈을 등록하는 역할
✔ createNativeModules() → 방금 만든 MyCustomEventModule을 React Native에 추가

 

 

3) MainApplication.java에 패키지 등록

import com.yourapp.MyCustomEventPackage;  // 추가

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new MyCustomEventPackage()  // 커스텀 패키지 추가
    );
}

 

이렇게 하면 React Native에서 MyCustomEventModule을 사용할 준비 완료! 🎉

 

🔴 3. JavaScript에서 네이티브 이벤트 사용하기

1) 이벤트 구독 (React Native)

이제 JS에서 네이티브 이벤트를 받을 준비를 해야 해!

📌 App.js 또는 이벤트를 받을 컴포넌트에 추가

import { NativeModules, DeviceEventEmitter } from 'react-native';
import { useEffect } from 'react';

const { MyCustomEventModule } = NativeModules;

const App = () => {
  useEffect(() => {
    // 1️⃣ 네이티브 이벤트 리스너 등록
    const eventListener = DeviceEventEmitter.addListener("CustomEvent", (event) => {
      console.log("📢 네이티브 이벤트 수신:", event.message);
    });

    // 2️⃣ 네이티브 이벤트 직접 호출 (테스트용)
    MyCustomEventModule.triggerEvent("안녕하세요, 네이티브에서 왔어요!");

    // 3️⃣ 언마운트 시 리스너 제거
    return () => {
      eventListener.remove();
    };
  }, []);

  return null;
};

export default App;

📌 설명

✔ DeviceEventEmitter.addListener("CustomEvent", callback) → 네이티브에서 발생한 이벤트를 감지
✔ MyCustomEventModule.triggerEvent("메시지") → JS에서 직접 네이티브 이벤트 실행
✔ useEffect() 내부에서 이벤트 리스너 등록 & 제거 (컴포넌트가 언마운트되면 리스너도 정리)

 

 

 

안드로이드에서도 알람앱의 기능 중 하나인 흔들기 기능을 추가해야 했다. 흔들기 기능을 모듈화해서 ReactNative 코드 안에서 직접 사용해야 했다. 그래서 우선 흔들기 기능을 따로 모듈화코드로 java 클래스로 우선 만든다

 

public class ShakeDetectorModule extends ReactContextBaseJavaModule implements SensorEventListener {


    private final String MODULE_NAME = "ShakeDetector";
    private final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
    private final int SHAKE_SLOP_TIME_MS = 500;
    private final int SHAKE_COUNT_RESET_TIME_MS = 3000;
    private long mShakeTimestamp;
    private int mShakeCount;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;


    public ShakeDetectorModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mSensorManager = (SensorManager) reactContext.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        }
    }

    @Override
    public String getName() {
        return MODULE_NAME;
    }


    @ReactMethod
    public void startShakeDetection() {
        if (mAccelerometer != null) {
            mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @ReactMethod
    public void stopShakeDetection() {
        mSensorManager.unregisterListener(this);
    }

    private void sendShakeEvent(boolean isShake) {
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("onShake", isShake);
    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        float gX = x / SensorManager.GRAVITY_EARTH;
        float gY = y / SensorManager.GRAVITY_EARTH;
        float gZ = z / SensorManager.GRAVITY_EARTH;
        float gForce = (float) Math.sqrt(gX * gX + gY * gY + gZ * gZ);
        if (gForce > SHAKE_THRESHOLD_GRAVITY) {
            final long now = System.currentTimeMillis();
            if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
                return;
            }
            if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
                mShakeCount = 0;
            }
            mShakeTimestamp = now;
            mShakeCount++;
            sendShakeEvent(true);
        } else {
            sendShakeEvent(false);
        }
    }
}

 

 

이렇게 우선 만들고 


public class AlarmPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new AlarmReceiverModule(reactContext));
        modules.add(new ShakeDetectorModule(reactContext));
        return modules;
    }

    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

 

에다가 새로운 생성자로 넣어주고 

 

ReactNative에서는 

 

/**
* 안드로이드 흔들기 시작
*/
export const startShakeInit = () => {
NativeModules.ShakeDetector.startShakeDetection();
};
/**
* 안드로이드 흔들기 종료
*/
export const stopShakeInit = () => {
NativeModules.ShakeDetector.stopShakeDetection();
};

 

이렇게 선언해주고 사용하면 된다.

 

끝!!

 

 

 

🎯 5. 정리

✅ RCTEventEmitter를 사용하면 네이티브(Android) → React Native로 이벤트를 전달 가능
✅ DeviceEventEmitter.addListener("이벤트명")을 사용해서 JS에서 이벤트 구독
✅ 네이티브 모듈을 만들고 triggerEvent() 메서드를 통해 JS에서 직접 실행 가능
멀티 서버 환경, 센서, 네트워크 상태 감지 등 실시간 이벤트 처리에 유용!

이제 React Native Android에서 커스텀 이벤트 모듈을 활용해서 더 다양한 기능을 구현할 수 있어! 🚀🔥

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."