이 가이드는 네이티브 프로그래밍과 Android 개발의 핵심 개념을 잘 알고 있는 개발자를 대상으로 합니다.
소개
이 섹션에서는 NDK 작동 방식에 관한 대략적인 설명을 제공합니다. Android NDK는 C 또는 C++('네이티브 코드')를 Android 앱에 삽입할 수 있게 해주는 도구 집합입니다. Android 앱에 네이티브 코드를 사용할 수 있는 기능은 다음 중 하나 이상을 실행하려는 개발자에게 특히 유용할 수 있습니다.
플랫폼 간 앱 이식
기존 라이브러리를 재사용하거나 재사용할 자체 라이브러리 제공
일부 경우, 특히 게임과 같이 계산 집약적인 앱의 성능 향상
작동 방식
이 섹션에서는 Android용 네이티브 애플리케이션 빌드에 사용되는 기본 구성요소를 소개하고 빌드 및 패키징 프로세스를 설명합니다.
기본 구성요소
앱을 빌드할 때는 다음 구성요소를 잘 파악하고 있어야 합니다.
네이티브 공유 라이브러리: NDK에서는 개발자의 C/C++ 소스 코드로부터 네이티브 공유 라이브러리 또는 .so 파일을 빌드합니다.
네이티브 정적 라이브러리: NDK에서는 개발자가 다른 라이브러리에 연결할 수 있는 정적 라이브러리 또는 .a 파일도 빌드할 수 있습니다.
자바 네이티브 인터페이스(JNI): JNI는 자바와 C++ 구성요소 간의 통신 채널 역할을 하는 인터페이스입니다. 이 가이드는 JNI 지식을 전제로 합니다. JNI에 관한 자세한 내용은 자바 네이티브 인터페이스 사양을 참고하세요.
Application Binary Interface(ABI): ABI는 앱의 기계어 코드가 런타임 시 시스템과 어떻게 상호작용할지 정확하게 정의합니다. NDK는 이 정의에 따라 .so 파일을 빌드합니다. 다양한 ABI는 서로 다른 아키텍처에 대응합니다. 즉, NDK에는 32비트 ARM, AArch64, x86, x86-64 각각에 맞는 ABI 지원이 포함되어 있습니다. 자세한 내용은 Android ABI를 참고하세요.
'JNI' 디렉터리에 이름, 플래그, 연결된 라이브러리, 컴파일할 소스 파일을 비롯하여 네이티브 라이브러리를 설명하는 Android.mk 파일을 만듭니다.
선택 사항으로 타겟 ABI, 도구 모음, 출시/디버그 모드, STL을 구성하는 Application.mk 파일을 만들 수 있습니다. 이러한 항목에 값을 지정하지 않으면 다음 기본값이 사용됩니다.
ABI: 지원 중단되지 않은 모든 ABI
모드: 출시
STL: 시스템
프로젝트의 jni 디렉터리에 네이티브 소스를 넣습니다.
ndk-build를 사용해 네이티브(.so, .a) 라이브러리를 컴파일합니다.
실행 가능한 .dex 파일을 생성하는 자바 구성요소를 빌드합니다.
앱 실행에 필요한 .so, .dex 및 기타 파일을 비롯하여 모든 항목을 APK 파일에 패키징합니다.
네이티브 액티비티 및 애플리케이션
Android SDK에서는 도우미 클래스 NativeActivity를 제공하며, 이를 사용하여 완전한 네이티브 액티비티를 작성할 수 있습니다. NativeActivity에서 Android 프레임워크와 네이티브 코드 간의 통신을 처리하므로 이를 서브클래스로 만들거나 메서드를 호출할 필요가 없습니다. AndroidManifest.xml 파일에서 애플리케이션을 네이티브로 선언하고 네이티브 애플리케이션을 만들기 시작하면 됩니다.
NativeActivity를 사용하는 Android 애플리케이션은 다른 애플리케이션에서 샌드박스된 자체 가상 머신에서 계속 실행됩니다. 따라서 JNI를 통해 Android 프레임워크 API에 계속 액세스할 수 있습니다. 하지만 센서, 입력 이벤트, 애셋 등 일부 경우에는 NDK에서 JNI를 통해 호출하지 않고 사용할 수 있는 네이티브 인터페이스를 제공합니다. 이러한 지원에 관한 자세한 내용은 네이티브 API를 참고하세요.
네이티브 액티비티 개발 여부와 상관없이 기존 Android 빌드 도구로 프로젝트를 만드는 것이 좋습니다. 이는 올바른 구조의 Android 애플리케이션을 빌드하고 패키징하는 데 도움이 됩니다.
Android NDK를 사용하면 다음 두 가지 방법으로 네이티브 액티비티를 구현할 수 있습니다.
native_activity.h 헤더는 NativeActivity 클래스의 네이티브 버전을 정의합니다. 이 헤더에는 네이티브 액티비티를 만드는 데 필요한 콜백 인터페이스와 데이터 구조가 포함되어 있습니다. 애플리케이션의 기본 스레드에서 콜백을 처리하므로 콜백 구현이 차단되면 안 됩니다. 콜백 구현이 차단되면 콜백이 반환될 때까지 기본 스레드가 응답하지 않으므로 ANR(애플리케이션 응답 없음) 오류가 발생할 수 있습니다.
android_native_app_glue.h 파일은 native_activity.h 인터페이스를 기반으로 빌드된 정적 도우미 라이브러리를 정의합니다. 이를 통해 다른 스레드가 생성되며 이 스레드에서 콜백 또는 이벤트 루프의 입력 이벤트 등을 처리합니다. 이러한 이벤트를 별도의 스레드로 이동하면 콜백으로 인해 기본 스레드가 차단되는 것을 방지할 수 있습니다.
<ndk_root>/sources/android/native_app_glue/android_native_app_glue.c 소스도 제공되며 이를 통해 구현을 수정할 수 있습니다.
이 정적 라이브러리의 자세한 사용 방법은 네이티브 액티비티 샘플 애플리케이션과 관련 문서를 살펴보세요. <ndk_root>/sources/android/native_app_glue/android_native_app_glue.h 파일의 주석에도 추가 자료가 제공됩니다.
네이티브 액티비티용 파일을 생성한 다음 ANativeActivity_onCreate 변수에서 명명된 함수를 구현합니다. 네이티브 액티비티가 시작될 때 앱에서 이 함수를 호출합니다. C/C++의 main과 유사한 이 함수는 개발자가 작성해야 하는 다양한 콜백 구현의 함수 포인터를 포함한 ANativeActivity 구조체 포인터를 받습니다. ANativeActivity->callbacks의 관련 콜백 함수 포인터를 콜백 구현으로 설정합니다.
ANativeActivity->instance 필드를 사용하려는 특정 데이터의 인스턴스 주소로 설정합니다.
시작할 때 활동에서 실행할 다른 작업이 있으면 구현합니다.
ANativeActivity->callbacks에 설정한 콜백의 나머지 부분을 구현합니다. 콜백이 호출되는 시점에 관한 자세한 내용은 활동 수명 주기 관리를 참고하세요.
애플리케이션의 나머지 부분을 개발합니다.
빌드 시스템의 네이티브 모듈을 설명하는 Android.mk file을 프로젝트의 jni/ 디렉터리에 생성합니다. 자세한 내용은 Android.mk를 참고하세요.
Android.mk 파일이 있다면 ndk-build 명령어를 사용하여 네이티브 코드를 컴파일합니다.
cd<path>/<to>/<project>
$NDK/ndk-build
평소와 같이 Android 프로젝트를 빌드하고 설치합니다. 네이티브 코드가 jni/ 디렉터리에 있으면 빌드 스크립트는 이 디렉터리에서 빌드된 .so 파일을 APK에 자동으로 패키징합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Concepts\n\nBefore you begin\n----------------\n\nThis guide assumes that you are already familiar with concepts inherent in\nnative programming and in [Android development](/develop).\n\nIntroduction\n------------\n\nThis section provides a high-level explanation of how the NDK works. The Android NDK is a set of\ntools allowing you to embed C or C++ (\"native code\") into your Android apps. The ability to use\nnative code in Android apps can be particularly useful to developers who wish to do one or more of\nthe following:\n\n- Port their apps between platforms.\n- Reuse existing libraries, or provide their own libraries for reuse.\n- Increase performance in certain cases, particularly computationally intensive ones like games.\n\nHow it works\n------------\n\nThis section introduces the main components used in building a native\napplication for Android, and goes on to describe the process of building and\npackaging.\n\n### Main components\n\nYou should have an understanding of the following components as you build your\napp:\n\n- Native shared libraries: The NDK builds these libraries, or `.so` files, from\n your C/C++ source code.\n\n- Native static libraries: The NDK can also build static libraries, or `.a`\n files, which you can link into other libraries.\n\n- Java Native Interface (JNI): The JNI is the interface via which the Java and\n C++ components talk to one another. This guide assumes knowledge of the JNI;\n for information about it, consult the [Java Native Interface Specification](http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html).\n\n- Application Binary Interface (ABI): The ABI defines exactly how your app's\n machine code is expected to interact with the system at runtime. The NDK\n builds `.so` files against these definitions. Different ABIs correspond to\n different architectures: The NDK includes ABI support for 32-bit ARM, AArch64,\n x86, and x86-64. For more information, see [Android\n ABIs](/ndk/guides/abis).\n\n- Manifest: If you are writing an app with no Java component to it, you must\n declare the [NativeActivity](/reference/android/app/NativeActivity) class in the\n [manifest](/guide/topics/manifest/manifest-intro). See [Use the\n native_activity.h interface](#na) for more detail on how to do this.\n\n### Flow\n\nThe general flow for developing a native app for Android is as follows:\n\n1. Design your app, deciding which parts to implement in Java, and which parts\n to implement as native code.\n\n | **Note:** While it is possible to completely avoid Java, you are likely to find the Android Java framework useful for tasks including controlling the display and UI.\n2. Create an Android app Project as you would for any other Android project.\n\n3. If you are writing a native-only app, declare the [NativeActivity](/reference/android/app/NativeActivity) class in\n `AndroidManifest.xml`. For more information, see the [Native activities and\n applications](#naa).\n\n4. Create an `Android.mk` file describing the native library, including name,\n flags, linked libraries, and source files to be compiled in the \"JNI\"\n directory.\n\n5. Optionally, you can create an `Application.mk` file configuring the target\n ABIs, toolchain, release/debug mode, and STL. For any of these that you do\n not specify, the following default values are used, respectively:\n\n - ABI: all non-deprecated ABIs\n - Mode: Release\n - STL: system\n6. Place your native source under the project's `jni` directory.\n\n7. Use ndk-build to compile the native (`.so`, `.a`) libraries.\n\n8. Build the Java component, producing the executable `.dex` file.\n\n9. Package everything into an APK file, containing `.so`, `.dex`, and other\n files needed for your app to run.\n\nNative activities and applications\n----------------------------------\n\nThe Android SDK provides a helper class, [NativeActivity](/reference/android/app/NativeActivity), that allows you to\nwrite a completely native activity. [NativeActivity](/reference/android/app/NativeActivity) handles the communication\nbetween the Android framework and your native code, so you do not have to\nsubclass it or call its methods. All you need to do is declare your application\nto be native in your `AndroidManifest.xml` file, and begin creating your native\napplication.\n\nAn Android application using [NativeActivity](/reference/android/app/NativeActivity) still runs in its own virtual\nmachine, sandboxed from other applications. You can therefore still access\nAndroid framework APIs through the JNI. In certain cases, such as for sensors,\ninput events, and assets, the NDK provides native interfaces that you can use\ninstead of having to call across the JNI. For more information about such\nsupport, see [Native APIs](/ndk/guides/stable_apis).\n\nRegardless of whether or not you are developing a native activity, we recommend\nthat you create your projects with the traditional Android build tools. Doing so\nhelps ensure building and packaging of Android applications with the correct\nstructure.\n\nThe Android NDK provides you with two choices to implement your native activity:\n\n- The [native_activity.h](/ndk/reference/native__activity_8h) header defines the native version of the [NativeActivity](/reference/android/app/NativeActivity) class. It contains the callback interface and data structures that you need to create your native activity. Because the main thread of your application handles the callbacks, your callback implementations must not be blocking. If they block, you might receive ANR (Application Not Responding) errors because your main thread is unresponsive until the callback returns.\n- The `android_native_app_glue.h` file defines a static helper library built on top of the [native_activity.h](/ndk/reference/native__activity_8h) interface. It spawns another thread, which handles things such as callbacks or input events in an event loop. Moving these events to a separate thread prevents any callbacks from blocking your main thread.\n\nThe `\u003cndk_root\u003e/sources/android/native_app_glue/android_native_app_glue.c`\nsource is also available, allowing you to modify the implementation.\n\nFor more information on how to use this static library, examine the\nnative-activity sample application and its documentation. Further reading is\nalso available in the comments in the\n`\u003cndk_root\u003e/sources/android/native_app_glue/android_native_app_glue.h`\nfile.\n\n### Use the native_activity.h interface\n\nTo implement a native activity with the [native_activity.h](/ndk/reference/native__activity_8h) interface:\n\n1. Create a `jni/` directory in your project's root directory. This directory\n stores all of your native code.\n\n2. Declare your native activity in the `AndroidManifest.xml` file.\n\n Because your application has no Java code, set `android:hasCode` to `false`. \n\n \u003capplication android:label=\"@string/app_name\" android:hasCode=\"false\"\u003e\n\n You must set the `android:name` attribute of the activity tag to\n [NativeActivity](/reference/android/app/NativeActivity). \n\n \u003cactivity android:name=\"android.app.NativeActivity\"\n android:label=\"@string/app_name\"\u003e\n\n | **Note:** You can subclass [NativeActivity](/reference/android/app/NativeActivity). If you do, use the name of the subclass instead of [NativeActivity](/reference/android/app/NativeActivity).\n\n The `android:value` attribute of the `meta-data` tag specifies the name of\n the shared library containing the entry point to the application (such as\n C/C++ `main`), omitting the `lib` prefix and `.so` suffix from the library\n name. \n\n \u003cmanifest\u003e\n \u003capplication\u003e\n \u003cactivity\u003e\n \u003cmeta-data android:name=\"android.app.lib_name\"\n android:value=\"native-activity\" /\u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"android.intent.action.MAIN\" /\u003e\n \u003ccategory android:name=\"android.intent.category.LAUNCHER\" /\u003e\n \u003c/intent-filter\u003e\n \u003c/activity\u003e\n \u003c/application\u003e\n \u003c/manifest\u003e\n\n3. Create a file for your native activity, and implement the function named in\n the [ANativeActivity_onCreate](/ndk/reference/group___native_activity#ga02791d0d490839055169f39fdc905c5e) variable. The app calls this function when the\n native activity starts. This function, analogous to `main` in C/C++, receives\n a pointer to an [ANativeActivity](/ndk/reference/struct_a_native_activity) structure, which contains function pointers\n to the various callback implementations that you need to write. Set the\n applicable callback function pointers in `ANativeActivity-\u003ecallbacks` to\n the implementations of your callbacks.\n\n4. Set the `ANativeActivity-\u003einstance` field to the address of any instance of\n specific data that you want to use.\n\n5. Implement anything else that you want your activity to do upon starting.\n\n6. Implement the rest of the callbacks that you set in\n `ANativeActivity-\u003ecallbacks`. For more information on when the callbacks are\n called, see [Managing the Activity Lifecycle](/training/basics/activity-lifecycle).\n\n7. Develop the rest of your application.\n\n8. Create an `Android.mk file` in the `jni/` directory of your project to\n describe your native module to the build system. For more information, see\n [Android.mk](/ndk/guides/android_mk).\n\n9. Once you have an [Android.mk](/ndk/guides/android_mk) file, compile your native code using the\n `ndk-build` command.\n\n cd \u003cpath\u003e/\u003cto\u003e/\u003cproject\u003e\n $NDK/ndk-build\n\n10. Build and install your Android project as usual. If your native code is in\n the `jni/` directory, the build script automatically packages the `.so`\n file(s) built from it into the APK.\n\nAdditional sample code\n----------------------\n\nTo download NDK samples, see [NDK Samples](https://github.com/android/ndk-samples)."]]