NDK (Native Development Kit) — egy eszközkészlet az alkalmazás egy részének C és C++ nyelven történő megírásához Android alá. Ellentétben a szokásos Android SDK-val, az NDK natív könyvtárakká (.so) fordítja a kódot, amelyek közvetlenül a processzoron futnak a virtuális gép rétege nélkül. A Google NDK Guides, 2026 szerint az NDK-t nagy teljesítményű számításokhoz, játékokhoz, hangfeldolgozáshoz és meglévő C/C++ projektek újrafelhasználásához használják. JNI (Java Native Interface) összeköti a natív kódot Kotlinnal és Javával.
Főbb pontok
NDK (Native Development Kit) — egy eszközkészlet C és C++ kód keresztfordításához végrehajtható könyvtárakká Android alá. Az NDK tartalmazza a Clang fordítót, a libc++ szabványos könyvtárat, az Android API fejlécfájlokat és build segédprogramokat. A fejlesztő natív kódot ír C vagy C++ nyelven, .so fájlokká (shared objects) fordítja, és JNI-n keresztül csatlakoztatja az alkalmazáshoz.
Az NDK nem helyettesíti az Android SDK-t, hanem kiegészíti azt. A teljes UI, lifecycle és rendszerszolgáltatások Kotlinban vagy Javában maradnak. A natív kód szűk feladatokat old meg: matematikai számítások, kriptográfia, kodekek, fizika játékokban. A Google ajánlja az NDK használatát csak akkor, ha az SDK nem biztosítja a szükséges teljesítményt vagy hozzáférést a hardveres képességekhez.
Az NDK története 2009-ben kezdődik (NDK r1). Ez idő alatt az eszközök egy kísérleti szkriptkészletből egy érett rendszerré fejlődtek CMake, LLDB hibakeresés és profilozás támogatással. 2026-ra a jelenlegi verzió NDK r27 Clang 19-cel, teljes C++20 támogatással és libc++-vel, mint egyetlen szabványos könyvtárral.
Az NDK hozzáférést biztosít a fejlesztőnek az Android alacsony szintű képességeihez natív API-ken keresztül. A fő használati forgatókönyvek közé tartozik: munka OpenGL ES és Vulkan segítségével 3D grafikához, hangfeldolgozás Oboe-n keresztül, kriptográfiai műveletek BoringSSL-en keresztül és NEON optimalizálások ARM-hez. Mindezek az API-k elérhetők C/C++-ból, és NDK-t igényelnek a fordításukhoz.
Emellett az NDK lehetővé teszi meglévő C/C++ könyvtárak újrafelhasználását anélkül, hogy Kotlinra kellene átírni őket. Ez különösen fontos a C++-ban hosszú múltra visszatekintő projekteknél — játékmotorok (Unity, Unreal Engine), számítógépes látáskönyvtárak (OpenCV) vagy kriptográfiai csomagok (OpenSSL). Ilyen esetekben az NDK éveket spórol a fejlesztésből.
| Komponens | Rendeltetés |
|---|---|
| Clang | C/C++ fordító C++20 támogatással |
| libc++ | Szabványos C++ könyvtár (egyetlen az NDK r27-ben) |
| CMake | Natív könyvtárak build rendszere |
| LLDB | Natív kód hibakereső az Android Studio-ban |
| ndk-build | Elavult build rendszer (CMake váltotta fel) |
A választás az NDK és a tiszta SDK között a feladattól függ. Az Android SDK kész Java/Kotlin API-kat biztosít a forgatókönyvek 90%-ához — munka hálózattal, fájlokkal, értesítésekkel, kamerával. Az NDK akkor csatlakozik, amikor ezek az API-k nem biztosítják a szükséges teljesítményt vagy funkcionalitást. Például a valós idejű hangfeldolgozás SDK-n keresztül lehetséges, de 50–200 ms késleltetéssel, míg a natív könyvtár Oboe-n keresztül 5–15 ms-ra csökkenti a késleltetést.
APK méret — egy másik tényező. Az NDK hozzáadása növeli az alkalmazás méretét, mivel minden ABI architektúra külön .so könyvtárat igényel. Az Android App Bundle (AAB) használata azonban enyhíti a problémát: a Google Play csak a felhasználó architektúrájának megfelelő könyvtárat szállítja. Egy tipikus natív projekt 1–10 MB-ot ad hozzá a telepítési mérethez az eszközön.
| Krérium | SDK (Kotlin/Java) | NDK (C/C++) |
|---|---|---|
| Teljesítmény | Közepes (JIT/AOT fordítás) | Magas (gépi kód) |
| Hang késleltetés | 50–200 ms | 5–15 ms Oboe-n keresztül |
| 3D grafika | Canvas/OpenGL Kotlin API-n keresztül | Közvetlen Vulkan/OpenGL |
| Fejlesztési komplexitás | Alacsony | Magas (memóriakezelés, JNI) |
| Kód hordozhatósága | Csak Android | Linux, Windows, macOS, iOS |
| APK méret | Minimális | +1–10 MB könyvtáranként |
Az NDK az Android SDK-tól külön telepíthető az SDK Manageren keresztül. Az NDK könyvtáron belül található a toolchain (fordítók), platformkönyvtárak, fejlécfájlok és segédprogramok. NDK Toolchain tartalmazza a Clang-ot az összes cél-ABI keresztfordításához: arm64-v8a, armeabi-v7a, x86_64 és x86. A fordító automatikusan kiválasztja a megfelelő architektúrát a CMake vagy ndk-build flag-ek alapján.
Az Android API-k natív kódhoz a sysroot/usr/include könyvtárban található fejlécfájlok által reprezentáltak. Ott találhatók az összes natív kódban elérhető API deklarációi: native_activity.h az Activity lifecycle-hoz, input.h a bemeneti eseményekhez, sensor.h az érzékelőkhöz. Ezen fejlécfájlok csatlakoztatása hozzáférést biztosít a hardveres képességekhez JNI réteg nélkül.
ndk/
toolchains/
llvm/prebuilt/windows-x86_64/
bin/ // Clang, ld, llvm-profdata
sysroot/ // Android API fejlécfájlok
platforms/
android-26/ // libc, libm, libdl API 26-hoz
android-34/
sources/
cxx-stl/ // libc++ fejlécek
build/
cmake/ // CMake toolchain fájl
Az NDK-n keresztül a következő natív API csoportok érhetők el: Native App Glue (Activity lifecycle kezelése C-ből), OpenGL ES 3.2 és Vulkan 1.3 (grafika), Oboe (alacsony késleltetésű hang), Neural Networks API (gépi tanulás az eszközön). Minden API rendelkezik fejlécfájllal és statikus/dinamikus könyvtárral az NDK összetételében.
A natív API-kkal való munkához nincs szükség JNI-re — a függvények közvetlenül a C/C++ kódból hívhatók meg. A Kotlin UI-val való interakcióhoz azonban továbbra is JNI szükséges. Ez a hibrid architektúra játékmotorokban fordul elő: grafika és fizika C++-ban (Vulkanon keresztül), menü és UI Kotlinban (Jetpack Compose-on keresztül).
JNI (Java Native Interface) — a natív kód meghívásának szabványos mechanizmusa a Java/Kotlin virtuális gépből. A fejlesztő Kotlinban deklarál egy külső függvényt az external kulcsszóval, és csatlakoztatja a .so könyvtárat a System.loadLibrary-n keresztül. A C++ oldalon a függvény a JNI elnevezési konvencióval kerül deklarálásra, amely kódolja a csomagot és az osztály nevét.
class NativeBridge {
companion object {
init {
System.loadLibrary("native-lib")
}
}
external fun stringFromJNI(): String
external fun fibonacci(n: Int): Long
external fun processBuffer(data: ByteArray): ByteArray
}
// Használat kódban
val bridge = NativeBridge()
println(bridge.stringFromJNI()) // "Hello from C++"
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_app_NativeBridge_stringFromJNI(
JNIEnv* env, jobject /* this */) {
std::string hello = "Hello from C++ NDK";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_example_app_NativeBridge_fibonacci(
JNIEnv* env, jobject /* this */, jint n) {
if (n <= 1) return n;
jlong a = 0, b = 1;
for (int i = 2; i <= n; i++) {
jlong temp = a + b;
a = b;
b = temp;
}
return b;
}
CMake — az NDK elsődleges build rendszere, amely felváltotta az elavult ndk-build-t. A CMakeLists.txt fájl leírja a forrásfájlokat, könyvtárakat és fordítási flag-eket. Az Android Studio automatikusan meghívja a CMake-t a projekt build-elésekor, ha az externalNativeBuild konfigurálva van a build.gradle-ben. A CMake make fájlokat generál minden cél-ABI-hoz, és párhuzamosan fordítja a natív kódot.
cmake_minimum_required(VERSION 3.22.1)
project("nativelib")
# Fejlécfájlok csatlakoztatása
include_directories(src/main/cpp/include)
# Natív könyvtár létrehozása
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/math_utils.cpp
src/main/cpp/audio_processor.cpp
)
# Android rendszerkönyvtárak csatlakoztatása
target_link_libraries(
native-lib
android
log
OpenSLES
# libc++ automatikusan csatlakozik
)
# Optimalizálási flag-ek
target_compile_options(native-lib PRIVATE -O3 -Wall -Wextra)
android {
defaultConfig {
ndk {
// Cél ABI-k a build-hez
abiFilters "arm64-v8a", "armeabi-v7a", "x86_64"
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
version "3.22.1"
}
}
buildTypes {
release {
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=Release"
}
}
}
}
}
ABI (Application Binary Interface) — a gépi kód formátuma, amely meghatározza a kompatibilitást az eszköz processzorával. Minden ARM vagy x86 architektúrának saját ABI-ja van. Az NDK külön fordítja a natív kódot minden megadott ABI-hoz. A leggyakoribb ABI-k 2026-ban: arm64-v8a (a modern eszközök 99%-a), armeabi-v7a (régi 32 bites eszközök), x86_64 (emulátor és Chromebook).
Az abiFilters megadása a build.gradle-ben csak a szükséges architektúrákra korlátozza a build-et, ami csökkenti a fordítási időt. A Google Play számára ajánlott az összes olyan ABI-t belefoglalni, amelyekkel a könyvtár kompatibilis — ez garantálja a működést minden eszközön. A Google Play Console lehetővé teszi az ABI-specifikus APK szállítás konfigurálását az App Bundle-on keresztül.
#include <jni.h>
#include <android/api-level.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_app_NativeBridge_getABIInfo(
JNIEnv* env, jobject /* this */) {
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
return env->NewStringUTF("armeabi-v7a");
#endif
#elif defined(__aarch64__)
return env->NewStringUTF("arm64-v8a");
#elif defined(__x86_64__)
return env->NewStringUTF("x86_64");
#elif defined(__i386__)
return env->NewStringUTF("x86");
#endif
return env->NewStringUTF("unknown");
}
| ABI | Architektúra | Bithossz | Eszközök |
|---|---|---|---|
| arm64-v8a | ARMv8-A | 64 bites | Szinte minden modern telefon |
| armeabi-v7a | ARMv7-A | 32 bites | Régi eszközök (2020 előtt) |
| x86_64 | x86-64 | 64 bites | Emulátor, Chromebook |
| x86 | x86 IA-32 | 32 bites | Elavult emulátorok |
Vizsgáljunk meg egy gyakorlati példát: egy matematikai könyvtár lebegőpontos számokkal való munkához. A natív kód C++-ban hatékonyabban végzi a számításokat, mint Kotlin, köszönhetően a NEON ARM utasításokhoz való közvetlen hozzáférésnek és a tömbhatárok ellenőrzésének hiányának futásidőben. Ez a példa az NDK használatának tipikus mintáját mutatja — nehéz számítások áthelyezése a natív rétegbe.
#include <jni.h>
#include <cmath>
#include <vector>
extern "C" JNIEXPORT jfloatArray JNICALL
Java_com_example_app_NativeBridge_normalizeArray(
JNIEnv* env, jobject, jfloatArray input) {
jsize len = env->GetArrayLength(input);
jfloat* elements = env->GetFloatArrayElements(input, nullptr);
// Átlag és szórás számítása
float sum = 0.0f, sumSq = 0.0f;
for (jsize i = 0; i < len; i++) {
sum += elements[i];
sumSq += elements[i] * elements[i];
}
float mean = sum / len;
float stddev = std::sqrt(sumSq / len - mean * mean);
// Normalizálás: (x - mean) / stddev
jfloat* result = new jfloat[len];
for (jsize i = 0; i < len; i++) {
result[i] = (elements[i] - mean) / stddev;
}
env->ReleaseFloatArrayElements(input, elements, JNI_ABORT);
jfloatArray output = env->NewFloatArray(len);
env->SetFloatArrayRegion(output, 0, len, result);
delete[] result;
return output;
}
A natív kód hibakereséséhez használja a __android_log_print makrót az android/log.h könyvtárból. Az üzenetek a Logcat-ben jelennek meg a Java/Kotlin naplók mellett. A naplózási szint (ANDROID_LOG_DEBUG, ANDROID_LOG_ERROR) segít az üzenetek szűrésében.
#include <android/log.h>
#define LOG_TAG "NativeLib"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
extern "C" JNIEXPORT void JNICALL
Java_com_example_app_NativeBridge_processData(
JNIEnv* env, jobject, jint count) {
LOGD("Processing %d items", count);
for (int i = 0; i < count; i++) {
// Nehéz feldolgozás
LOGD("Item %d processed", i);
}
LOGD("Processing complete");
}
Gyakran Ismételt Kérdések
Nem. A legtöbb alkalmazáshoz elegendő az SDK Kotlinban. Az NDK szükséges nagy teljesítményű feladatokhoz: valós idejű hang/videó feldolgozás, 3D grafika, kriptográfia vagy meglévő C/C++ projektek újrafelhasználása.
Az NDK a Clang-ot használja az LLVM toolchain-ből. Az NDK r23-tól kezdve a GCC teljesen eltávolításra került. A Clang keresztfordítja a kódot az összes Android ABI-hoz: arm64-v8a, armeabi-v7a, x86_64, x86.
ABI (Application Binary Interface) — a gépi kód formátuma, amely meghatározza a processzorral való kompatibilitást. Az NDK külön építi a .so könyvtárakat minden ABI-hoz. arm64-v8a — a fő ABI a modern Android eszközök számára.
Igen. Az Android Studio támogatja a LLDB-t — a natív kód hibakeresőjét. Lehet töréspontokat elhelyezni C++ fájlokban, megtekinteni változókat és a hívási vermet. A működéshez NDK és LLDB plugin szükséges.
Minden natív könyvtár 100 KB — néhány MB-ot ad hozzá az APK-hoz. Minden ABI-hoz külön .so könyvtár szükséges. Az Android App Bundle csak a megfelelő architektúrát szállítja a felhasználónak, csökkentve a telepítési méretet.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is