ReactNative: 기존 네이티브 프로젝트에 이식하기 (+native 메소드 호출)


(글 작성한 시점의 최신 ReactNative ver: 0.41)


1. What I want to do


내가 원한건 이런 화면이다.

전체적으로 Android 네이티브 코드로 제작되어있는데, (Toolbar나 DraweLayout 등...)
   ① 기본적인 메뉴들은 네이티브 화면이 보여지지만
   ② 특정 메뉴는 ReactNative로 코딩된 화면 노출
   ③ 어떤 화면에서는 아예 혼합되어있어야 하고 
   ④ 아예 ReactNative로만 된 activity도 2 dept로 호출할 수 있는 앱
   + 그리고 각 ReactNative 화면에서도 자유롭게 네이티브의 메소드들을 호출할 수 있게끔.


▼ gif로 보자면 대충 이런식으로 흐른다 . (연두색은 네이티브 / 하늘색은 ReactNative)

 





2. What I should do
  1. 일단 일반적인 방법으로 AndroidStudio에서 새로운 프로젝트를 생성해준다.
  2. 네이티브 코드로 대충 뼈대를 잡아준다. DrawerLayout, SlidingTab 등등..
  3. ReactNative 사용 가능 환경 설정을 해준다. (Integration With Existing Appspackage.jsonindex.android.js 만들고 gradle 설정 작업 등을 한다. 
  4. ReactNative를 보여줄 부분에 ReactRootView를 사용하여 dynamically adding 해준다. 대충 이런식으로.. 이 부분은 위에 링크한 공식 문서를 참고해 충분히 응용 가능하다.
  5. ReactNative에서 네이티브 내의 메소드들을 호출하기 위해 모듈을 생성한다. ReactContextBaseJavaModule를 오버라이딩 받아야하며, getName()에서의 리턴값은 ReactNative에서 import 시 명시할 모듈이름이기 때문에 유의해서 짓는다. 그리고 @ReactMethod 어노테이션과 함께 원하는 메소드들을 생성해주면 된다. 이 어노테이션이 달린 메소드들은 ReactNative에서 호출이 가능하다.
  6. 모듈들을 패키지로 묶어준다. ReactPackage를 상속받아서 createNativeModules 안에서 모듈들을 add() 해주면 된다. 나머지 메소드들에서는 필요한게 아니라면 일단  Collections.emptyList() 들을 리턴해주면 된다.
  7. 만든 모듈을 사용하려면 4번의 ReactRootView를 사용한 곳에서 필수로 .addPacakge() 해주어야 한다. 아래 코드로 보면 6번 라인이 신규로 추가된 라인이다.
  8. 사용할 때는 별도 작업 없이 import 만 잘 명시해주면 NativeModules.모듈명.메소드명();로 쉽게 사용 가능하다. 모듈을 사용하기 위해서 기존 코드에서 2줄만 업데이트했다. 하기 코드에서는 12번라인의 import문과 16번라인의 사용문.





3. Fixed error

64비트 라이브러리 이슈, 컴파일 에러, 런타임 에러 등등 많았지만..

일단 ReactNative에서 네이티브 메소드들을 호출하기 위한 작업 과정에서 발생했던 이슈는 크게 2가지다. (물론 둘 다 해결하고 나니 부끄러운 이슈들이었다...ㅎㅎ...)

  1. undefined is not an object (evaluating...): js에서 모듈을 못 찾는 이슈 
    가이드 문서를 보면 사실 getPackages()Appication에 추가하라고 한다. 그러나 나 같은 경우 ReactRootView를 사용하여 ReactInstanceManager를 수동으로 설정하므로 ReactInstanceManager 생성하는 부분에 추가 작업을 해줘야 한다. (앞에서의 7번 step) 뭐 물론 .setApplication() 하는 부분에 해당 Appication을 명시해주는 것도 해결방법일듯 하다.
  2. 모듈 안에서 (네이티브 메소드) getCurrentActivity() 가 null로 반환되는 이슈
    ReactInstanceManager.onHostResume()에서 파라미터로 activity를 넣어주기 때문에 이 부분이 꼭 되어있어야 한다. 나 같은 경우는 onResume()에 onHostResume()하는 부분은 들어가있었지만, ReactInstanceManager가 애초에  onResume() 이후로 생성하도록 코딩이 되어있어서 (사용시에 생성하도록.. 즉, 메뉴 이동이 일어나야 생성한다.) onResume()에서 ReactInstanceManager가 null인 까닭에 onHostResume()가 제대로 불리지 않아서 activity가 셋팅되지 않았었다.





마치며

다른 회사와 협업을 하는 과정에서 우리가 전체적인 틀을 만들고 특정 메뉴들만 협력업체가 개발을 하게 되었었는데, 협력업체가 본인들 화면을 ReactNative로 개발하겠다는 것이 해당 테스트 앱을 만들게 된 계기였다. (우린 네이티브 코드로 개발을 하는 상황)

아마 이런식으로 화면을 붙이고 ReactNative에서도 자유롭게 네이티브 메소드들을 호출할 수 있도록 설정하면, ReactNative의 서드파티 브릿지 개발 한계 이슈라던지 하는 문제점들이 어느 정도 커버 가능할 것으로 보인다.

댓글

이 블로그의 인기 게시물

5년차의 슬럼프

10대 여고생이 만난 프로그래밍 - 마이크로소프트웨어 31주년 컨퍼런스

About Me