본문 바로가기

Programming/Android

NDK란?

NDK란? (https://developer.android.com/ndk/guides/concepts.html?hl=ko)

  • 소개
    • Android NDK는 Android 앱에 C 또는 C++("네이티브 코드")를 삽입할 수 있게 해주는 도구 집합이다.
      Android 앱에 네이티브 코드를 사용할 수 있는 능력은 다음 중 한 가지 이상을 수행하려는 개발자에게 특히 유용할 수 있다.
      • 플랫폼 간의 앱 이식
      • 기존 라이브러리를 재사용하거나 재사용할 고유의 라이브러리 제공
      • 특정한 경우, 특히 게임과 같이 집약적인 계산 작업이 이루어지는 앱의 성능 향상
  • 작동 방식
    • 앱을 빌드할 때는 다음 구성 요소에 대해 잘 파악하고 있어야 한다.
      • 네이티브 공유 라이브러리: NDK는 개발자의 C/C++ 소스 코드에서 이러한 라이브러리 또는 .so파일을 빌드한다.
      • 네이티브 정적 라이브러리: NDK는 정적 라이브러리나 .a 파일을 빌드할 수도 있는데, 이들을 다른 라이브러리로 링크할 수 있다.
      • 자바 네이티브 인터페이스(JNI): JNI는 자바 및 C++ 구성 요소의 상호 통신 채널 역할을 하는 인터페이스이다.
        이 가이드에서는 독자가 JNI에 대한 지식을 가지고 있다고 가정하고 설명한다.
        JNI에 대한 자세한 내용은 자바 네이티브 인터페이스 사양(https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html)을 참조해라.
      • 애플리케이션 바이너리 인터페이스(ABI): ABI는 앱의 기계어 코드가 런타임에 시스템과 어떻게 상호작용할지를 정확히 정의한다. NDK는 이러한 정의에 대해 .so 파일을 빌드한다. 다양한 ABI가 각기 다른 아키텍처에 대응된다.
        NDK는 32비트 ARM, AArch64, x86, x86-64에 대한 ABI 지원을 포함한다. 자세한 내용은 ABI 관리(https://developer.android.com/ndk/guides/abis.html?hl=ko)를 참조해라.
      • 매니페스트: 자바 구성 요소가 없는 앱을 작성 중인 경우, 반드시 매니페스트에서 NativeActivity 클래스를 선언해야 한다. 네이티브 액티비티 및 애플리케이션의 "native_activity.h 인터페이스 사용" 제목 아래에서 이 방법의 자세한 설명을 제공했다.
  • 흐름
    • Android용 네이티브 앱 개발을 위한 일반적인 흐름은 다음과 같다.
      1. 어떤 부분을 자바로 구현하고 어떤 부분을 네이티브 코드로 구현할지 결정해 앱을 디자인하낟.
        • 참고: 자바 사용을 완전히 피할 수는 있지만, 디스플레이와 UI의 제어를 비롯한 다양한 작업에 Android 자바 프레임워크가 유용하다는 사실을 알 수 있을 것이다.
      2. 다른 Android 프로젝트의 경우와 마찬가지로 Android 앱 프로젝트를 만든다.
      3. 네이티브 코드로만 된 앱을 작성하는 것이라면, AndroidManifest.xml에서 NativeActivity 클래스를 선언한다.
        자세한 내용은 다음 내용의 네이티브 액티비티 및 애플리케이션을 참조해라.
      4. "JNI" 디렉토리에 이름, 플래그, 링크된 라이브러리, 컴파일할 소스 파일을 비롯해 네이티브 라이브러리를 설명하는 Android.mk 파일을 만든다.
      5. 선택 사항으로, 대상 ABI, 툴체인, 릴리스/디버그 모드, STL을 구성하는 Application.mk 파일을 만들 수 있다.
        이들 중 지정하지 않는 항목에 대해서는 각각 다음의 기본값이 사용된다.
        • ABI: 지원이 중단되지 않은 모든 ABI
        • 툴체인: Clang
        • 모드: 릴리스
        • STL: 시스템
      6. 프로젝트의 jni 디렉토리에 네이티브 소스를 넣는다.
      7. ndk-build를 사용해 네이티브(.so, .a) 라이브러리를 컴파일한다.
      8. .dex 실행 파일을 생성하는 자바 구성 요소를 빌드한다.
      9. 앱 실행에 필요한 .so, .dex 및 기타 파일을 포함한 모든 것을 APK 파일에 패키징한다.
  • 네이티브 액티비티 및 애플리케이션
    • Android SDK는 완전한 네이티브 액티비티를 작성할 수 있게 해주는 도우미 클래스 NativeActivity를 제공한다.
      NativeActivity가 Android 프레임워크와 네이티브 코드 간의 통신을 처리하므로 이를 하위 클래스로 처리하거나 메서드를 호출할 필요가 없다. AndroidManifest.xml 파일에서 애플리케이션을 네이티브로 선언하고, 네이티브 애플리케이션을 만들기 시작하면 된다.
    • NativeActivity를 사용하는 Android 애플리케이션은 다른 애플리케이션에서 샌드박싱된 자체 가상 머신에서 계속 실행된다. 따라서 JNI를 통해 Android 프레임워크 API에 계속 액세스할 수 있다. 하지만 센서, 입력 이벤트, 자산 등의 경우에는 NDK가 JNI를 호출할 필요 없이 사용할 수 있는 네이티브 인터페이스를 제공한다.
      이러한 지원에 대한 자세한 내용은 Android NDK 네이티브 API를 참조하세요.
    • 네이티브 액티비티의 개발 여부와 상관없이, 기존의 Android 빌드 도구로 프로젝트를 만드는 것이 좋다. 그러면 올바른 구조의 Android 애플리케이션을 빌드하고 패키징하는 데 도움이 된다.
    • Android NDK를 사용하면 다음 두 가지 방법으로 네이티브 액티비티를 구현할 수 있다.
      1. native_activity.h 헤더는 NativeActivity 클래스의 네이티브 버전을 정의한다. 이 헤더에는 네이티브 액티비티를 만드는 데 필요한 콜백 인터페이스와 데이터 구조가 포함되어 있다. 애플리케이션의 메인 스레드가 콜백을 처리하기 때문에 콜백 구현이 메인 스레드를 차단하면 안 된다. 차단할 경우에는 콜백이 확인될 때까지 메인 스레드가 응답하지 않기 때문에 ANR(애플리케이션 응답 없음) 오류가 발생할 수 있다.
      2. android_native_app_glue.h 파일은 native_activity.h 인터페이스를 기반으로 빌드된 정적 도우미 라이브러리를 정의한다. 이것이 또 다른 스레드를 생성해, 이 스레드가 콜백 또는 이벤트 루프의 입력 이벤트 등을 처리한다. 이러한 이벤트를 별개의 스레드로 이동하면 어떤 콜백도 메인 스레드를 차단하지 못하게 된다.
    • /sources/android/native_app_glue/android_native_app_glue.c 소스도 사용 가능하며, 이를 통해 구현을 수정할 수 있다.

'Programming > Android' 카테고리의 다른 글

AndroidManifest란?  (0) 2019.05.19
Application.mk란?  (0) 2019.05.19
Android.mk란?  (0) 2019.05.19
ABI란?  (0) 2019.04.22
Gradle이란?  (0) 2019.04.16