NDK (Native Development Kit) — je sada nástrojů pro psaní části aplikace v C a C++ pro Android. Na rozdíl od běžného Android SDK, NDK kompiluje kód do nativních knihoven (.so), které pracují přímo s procesorem bez vrstvy virtuálního stroje. Podle Google NDK Guides, 2026, se NDK používá pro vysoce výkonné výpočty, hry, zpracování zvuku a opětovné použití stávajících C/C++ projektů. JNI (Java Native Interface) spojuje nativní kód s Kotlin a Java.
Hlavní body
NDK (Native Development Kit) — je sada nástrojů pro křížovou kompilaci kódu C a C++ do spustitelných knihoven pro Android. NDK zahrnuje kompilátor Clang, standardní knihovnu libc++, hlavičkové soubory Android API a nástroje pro sestavení. Vývojář píše nativní kód v C nebo C++, kompiluje jej do .so souborů (shared objects) a připojuje k aplikaci přes JNI.
NDK nenahrazuje Android SDK, ale doplňuje jej. Celé UI, lifecycle a systémové služby zůstávají v Kotlin nebo Java. Nativní kód řeší úzké úkoly: matematické výpočty, kryptografie, kodeky, fyzika ve hrách. Google doporučuje používat NDK pouze tehdy, když SDK neposkytuje požadovaný výkon nebo přístup k hardwarovým možnostem.
Historie NDK začíná v roce 2009 (NDK r1). Během této doby nástroje prošly cestou od experimentální sady skriptů k vyspělému systému s podporou CMake, ladění LLDB a profilování. K roku 2026 je aktuální verzí NDK r27 s Clang 19, plnou podporou C++20 a libc++ jako jedinou standardní knihovnou.
NDK poskytuje vývojáři přístup k nízkoúrovňovým možnostem Androidu prostřednictvím nativních API. Hlavní scénáře použití zahrnují: práci s OpenGL ES a Vulkan pro 3D grafiku, zpracování zvuku přes Oboe, kryptografické operace přes BoringSSL a NEON optimalizace pro ARM. Všechna tato API jsou přístupná z C/C++ a vyžadují NDK pro kompilaci.
Kromě toho NDK umožňuje opětovné použití stávajících C/C++ knihoven bez přepisování do Kotlin. To je zvláště důležité pro projekty s dlouholetou historií v C++ — herní engine (Unity, Unreal Engine), knihovny počítačového vidění (OpenCV) nebo kryptografické balíčky (OpenSSL). V takových případech NDK šetří roky vývoje.
| Komponenta | Účel |
|---|---|
| Clang | Kompilátor C/C++ s podporou C++20 |
| libc++ | Standardní knihovna C++ (jediná v NDK r27) |
| CMake | Systém sestavení nativních knihoven |
| LLDB | Ladicí nástroj nativního kódu v Android Studio |
| ndk-build | Zastaralý systém sestavení (nahrazen CMake) |
Volba mezi NDK a čistým SDK závisí na úkolu. Android SDK poskytuje hotová Java/Kotlin API pro 90% scénářů — práce se sítí, soubory, oznámeními, kamerou. NDK se připojuje, když tato API neposkytují požadovaný výkon nebo funkčnost. Například zpracování zvuku v reálném čase přes SDK je možné, ale se zpožděním 50–200 ms, zatímco nativní knihovna přes Oboe snižuje zpoždění na 5–15 ms.
Velikost APK — další faktor. Přidání NDK zvyšuje velikost aplikace, protože každá ABI architektura vyžaduje samostatnou .so knihovnu. Použití Android App Bundle (AAB) však problém zmírňuje: Google Play doručuje uživateli pouze knihovnu pro jeho architekturu. Typický nativní projekt přidává 1–10 MB k velikosti instalace na zařízení.
| Kritérium | SDK (Kotlin/Java) | NDK (C/C++) |
|---|---|---|
| Výkon | Střední (JIT/AOT kompilace) | Vysoký (strojový kód) |
| Zpoždění zvuku | 50–200 ms | 5–15 ms přes Oboe |
| 3D grafika | Přes Canvas/OpenGL Kotlin API | Přímo Vulkan/OpenGL |
| Složitost vývoje | Nízká | Vysoká (správa paměti, JNI) |
| Přenositelnost kódu | Pouze Android | Linux, Windows, macOS, iOS |
| Velikost APK | Minimální | +1–10 MB na knihovnu |
NDK se instaluje odděleně od Android SDK přes SDK Manager. Uvnitř adresáře NDK se nachází toolchain (kompilátory), platformní knihovny, hlavičkové soubory a nástroje. Toolchain NDK zahrnuje Clang pro křížovou kompilaci pro všechny cílové ABI: arm64-v8a, armeabi-v7a, x86_64 a x86. Kompilátor automaticky vybírá správnou architekturu na základě přepínačů CMake nebo ndk-build.
Android API pro nativní kód jsou reprezentována hlavičkovými soubory v adresáři sysroot/usr/include. Jsou zde deklarace pro všechna API dostupná v nativním kódu: native_activity.h pro lifecycle Activity, input.h pro vstupní události, sensor.h pro senzory. Připojení těchto hlaviček poskytuje přístup k hardwarovým možnostem bez vrstvy JNI.
ndk/
toolchains/
llvm/prebuilt/windows-x86_64/
bin/ // Clang, ld, llvm-profdata
sysroot/ // Hlavičkové soubory Android API
platforms/
android-26/ // libc, libm, libdl pro API 26
android-34/
sources/
cxx-stl/ // Hlavičky libc++
build/
cmake/ // Soubor toolchain CMake
Prostřednictvím NDK jsou dostupné následující skupiny nativních API: Native App Glue (správa lifecycle Activity z C), OpenGL ES 3.2 a Vulkan 1.3 (grafika), Oboe (zvuk s nízkou latencí), Neural Networks API (strojové učení na zařízení). Každé API má hlavičkový soubor a statickou/dynamickou knihovnu v rámci NDK.
Pro práci s nativními API není potřeba JNI — funkce jsou volány přímo z C/C++ kódu. Pro interakci s UI v Kotlin je však stále vyžadován JNI. Tato hybridní architektura se vyskytuje v herních enginech: grafika a fyzika v C++ (přes Vulkan), menu a UI v Kotlin (přes Jetpack Compose).
JNI (Java Native Interface) — standardní mechanismus volání nativního kódu z virtuálního stroje Java/Kotlin. Vývojář deklaruje v Kotlin externí funkci s klíčovým slovem external a připojí .so knihovnu přes System.loadLibrary. Na straně C++ je funkce deklarována pomocí konvence pojmenování JNI, která kóduje balíček a název třídy.
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
}
// Použití v kódu
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 — hlavní systém sestavení pro NDK, který nahradil zastaralý ndk-build. Soubor CMakeLists.txt popisuje zdrojové soubory, knihovny a přepínače kompilace. Android Studio automaticky volá CMake při sestavení projektu, pokud je nakonfigurován externalNativeBuild v build.gradle. CMake generuje make soubory pro každý cílový ABI a kompiluje nativní kód paralelně.
cmake_minimum_required(VERSION 3.22.1)
project("nativelib")
# Připojení hlavičkových souborů
include_directories(src/main/cpp/include)
# Vytvoření nativní knihovny
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/math_utils.cpp
src/main/cpp/audio_processor.cpp
)
# Připojení systémových knihoven Android
target_link_libraries(
native-lib
android
log
OpenSLES
# libc++ se připojuje automaticky
)
# Přepínače optimalizace
target_compile_options(native-lib PRIVATE -O3 -Wall -Wextra)
android {
defaultConfig {
ndk {
// Cílová ABI pro sestavení
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) — je formát strojového kódu, který určuje kompatibilitu s procesorem zařízení. Každá architektura ARM nebo x86 má své vlastní ABI. NDK kompiluje nativní kód samostatně pro každé zadané ABI. Nejrozšířenější ABI v roce 2026: arm64-v8a (99% moderních zařízení), armeabi-v7a (stará 32-bitová zařízení), x86_64 (emulátor a Chromebook).
Uvedení abiFilters v build.gradle omezuje sestavení pouze na potřebné architektury, což zkracuje dobu kompilace. Pro Google Play se doporučuje zahrnout všechna ABI, se kterými je knihovna kompatibilní — to zaručuje fungování na všech zařízeních. Google Play Console umožňuje konfigurovat doručování ABI-specifických APK prostřednictvím App Bundle.
#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 | Architektura | Bit | Zařízení |
|---|---|---|---|
| arm64-v8a | ARMv8-A | 64-bit | Téměř všechny moderní telefony |
| armeabi-v7a | ARMv7-A | 32-bit | Stará zařízení (do 2020) |
| x86_64 | x86-64 | 64-bit | Emulátor, Chromebook |
| x86 | x86 IA-32 | 32-bit | Zastaralé emulátory |
Podívejme se na praktický příklad: matematická knihovna pro práci s čísly s plovoucí desetinnou čárkou. Nativní kód v C++ provádí výpočty efektivněji než Kotlin, díky přímému přístupu k NEON ARM instrukcím a absenci kontrol hranic polí během běhu. Tento příklad ukazuje typický vzor použití NDK — přesun těžkých výpočtů do nativní vrstvy.
#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);
// Vypočítáme průměr a směrodatnou odchylku
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);
// Normalizace: (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;
}
Pro ladění nativního kódu použijte makro __android_log_print z knihovny android/log.h. Zprávy se objevují v Logcat vedle Java/Kotlin logů. Úroveň logování (ANDROID_LOG_DEBUG, ANDROID_LOG_ERROR) pomáhá filtrovat zprávy.
#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++) {
// Těžké zpracování
LOGD("Item %d processed", i);
}
LOGD("Processing complete");
}
Často kladené otázky
Ne. Pro většinu aplikací stačí SDK v Kotlin. NDK je potřeba pro úlohy s vysokým výkonem: zpracování zvuku/videa v reálném čase, 3D grafika, kryptografie nebo opětovné použití stávajících C/C++ projektů.
NDK používá Clang z LLVM toolchain. Od NDK r23 bylo GCC zcela odstraněno. Clang křížově kompiluje kód pro všechna Android ABI: arm64-v8a, armeabi-v7a, x86_64, x86.
ABI (Application Binary Interface) — formát strojového kódu určující kompatibilitu s procesorem. NDK sestavuje .so knihovny pro každé ABI samostatně. arm64-v8a — hlavní ABI pro moderní Android zařízení.
Ano. Android Studio podporuje LLDB — ladicí nástroj nativního kódu. Lze nastavovat breakpointy v C++ souborech, prohlížet proměnné a zásobník volání. Pro fungování je vyžadován NDK a plugin LLDB.
Každá nativní knihovna přidává 100 KB — několik MB do APK. Pro každé ABI je potřeba samostatná .so knihovna. Android App Bundle doručuje uživateli pouze odpovídající architekturu, čímž snižuje velikost instalace.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také