ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React Native 개발시 Native 기능 개발후 연결 방법 ( 안드로이드 )
    수상한 프로그래머/React Native 2020. 9. 9. 13:52
    반응형

    React Native를 개발하다보면 React Native에서 제공해주지 않는 Native 기능을 써야할 때가 오게된다.

    왠만한 기능은 이미 Git에 보면 나와 있지만 없을 경우 직접 Native 언어로 개발후 React Native와 연결해서

    써야한다. 이번에 USB관련 안드로이드 자체 기능을 써야할 기회(? 위기ㅠㅠ)가 와서

    안드로이드로 개발후 React Native에 연결해 보았다.

    연결방법은 아래와 같다 ㅎㅎ 차근차근 따라해봅시다~!

     

    1. 안드로이드 최대한 소스를 정리하여 개발한다.

    -> 당연히 안드로이드에서 잘 돌아가야지 React Native에서도 돌아간다 ㅎ;;

    2. React Native 프로젝트로 돌아와 MainActivity.java가 위치한 곳에 XXXModue.java와 XXXPackage.java 파일을 만들어준다.

    -> 파일명은 기능명끝에 Module과 Package를 붙여주어 구분하면 좋다. 각각의 역할이 다르기 때문!

        Module은 자신이 개발한 Native기능을 구현해주는 곳이고 Package는 React Native에 연결해주는 부분이다.

    3. XXXModule.java 상단에 React Native 에서 제공해주는 라이브러리를 불러온다.

    // Import React Native dependencies
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContext;
    import com.facebook.react.bridge.Callback;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    import com.facebook.react.uimanager.IllegalViewOperationException;
    import com.facebook.react.uimanager.PixelUtil;

     

    4.기존 extends Activity로 상속받았던 부분은 extends ReactContextBaseJavaModule로 바꿔준다.

    5. private static ReactApplicationContext reactContext; 라고 변수를 선언한뒤

    생성자함수를 아래와 같이 구현해준다. 그리고 getName을 선언해 주는데 이게 우리가 나중에 React Native에서

    Import 해올 패키지 명이다.

    public class UARTUsbModule extends ReactContextBaseJavaModule{
    	private static ReactApplicationContext reactContext;
    	public UARTUsbModule(ReactApplicationContext reactContext) {
            super(reactContext);
            this.reactContext = reactContext;
        }
        @Override
        public String getName() {
            return "UARTUsb";  // 나중에 React Native에서 불러올 이름
        }
    
    ........

    6. 기존 소스를 그대로 넣어준다. 이때 onCreate나 on Resume등 Activity에서 제공해주는 함수들은 Activity를 상속받지 않으니

    따로 다른 함수로 정의해주어야 한다. 

    7. React Native에서 쓸 함수에 @ReactMethod 어노테이션을 붙여준다.

    @ReactMethod
    public void initUART() {
    
       // Context from reactContext
       Context context = reactContext;
       Activity activity = getCurrentActivity();
            
     ......

    Tip을 주자면 onCreate같은 함수를  재정의하여 React Native함수로 쓸수있게 해놓았다.

    React Native에서 불러주면 되니깐 -ㅠ-

    8. 대부분 React Native에서 쓸 함수를 정의 했다면 XXXPackage.java에 아래와 같이 React Native  라이브러리를 불러온다.

    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.UIManagerModule;
    import com.facebook.react.uimanager.ViewManager;

    9. 그다음 ReactPackage 인터페이스를 구현해준다.

    public class UARTUsbPackage implements ReactPackage {
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
    
            modules.add(new UARTUsbModule(reactContext)); // XXXModule의 객체생성
    
            return modules;
        }
    }
    

      -> 이때 기존에 정의한 XXXUsbModule의 객체를 만들어주고 modules에 넣어준다.

    10. MainApplication.java에서 패키지를 불러온다.

    -> 나같은 경우는 Navigation을 쓰고 있기때문에 이렇게 기존다른 패키지처럼 불러와 주면 되었다.

    11. React Native 구현은 우선 XXXutil.js 파일을 아래와 같이 만들어준다

    import { NativeModules } from 'react-native';
    
    module.exports = NativeModules.UARTUsb; //아까 5번에서 정의한 getName 이름

      -> NativeModules.뒤에 아까 getName으로 정의한 이름을 넣어주면 된다.

    12. 필요한 소스에서 상단에 XXXutil.js 파일을 불러와주고 7번에서 React Native에서 정의한 함수들을 쓸수 있다.

    import UARTUsb from 'libs/XXXUtil';  //XXXUtil파일에서 UARTUsb를 불러온다.
    
    
    ......
    
    
    UARTUsb.initUART();

     

    안짜봤을땐 막연히 어렵겠다 생각했는데 차근차근 해보니 어렵지는 않았다. 

    다만 Context객체의 경우 기존 Activity Context에서 ReactNative Context로 변경되어 이부분을 주의하여

    수정해야한다.  휴~~

    간단요약 : 모듈과 패키지 파일을 만들고 모듈에는 기능정의 패키지는 모듈을 연결 시켜주고 React Native에서 불러와서 쓰면 끝

     

    참고로 XXXModule.java에서 로직실행후 값을 리턴받고 싶을때는 callBack함수를 넘겨서 받아야한다.

    errorCallback, successCallback함수를 받아서 invoke로 값을 넣어준다.

    @ReactMethod
        public void getValue(Callback errorCallback,
                            Callback successCallback) {
            try {
                String result = null;
                if(resultText == null){
                    result = "값없음";
                }else{
                    result = resultText.toString();
                }
                successCallback.invoke(resultText.toString());
            } catch (IllegalViewOperationException e) {
                errorCallback.invoke(e.getMessage());
            }
        }
    

    React Native 에서는 아래와 같이 callBack함수를 정의하여 쓰면 된다.

    UARTUsb.getUART((msg) => {
          //errorCallback 함수
          this.setState({
            output: msg,
          });
        },
        (output) => {
          //successCallback 함수
          this.setState({
            output,
          });
        });

     

    반응형

    댓글

Designed by Tistory.