NDK Android: bu nədir, Native Development Kit və C++ üçün JNI

Müəllif: IT Sectr Dərc olunub: 2026-02-09 Oxuma vaxtı: 10 dəq

NDK (Native Development Kit) — Android üçün proqramın bir hissəsini C və C++ dilində yazmaq üçün alətlər dəstidir. Adi Android SDK-dan fərqli olaraq, NDK kodu birbaşa prosessorda virtual maşın təbəqəsi olmadan işləyən yerli kitabxanalara (.so) kompilə edir. Google NDK Guides, 2026 məlumatına görə, NDK yüksək performanslı hesablamalar, oyunlar, audio emalı və mövcud C/C++ layihələrinin təkrar istifadəsi üçün istifadə olunur. JNI (Java Native Interface) yerli kodu Kotlin və Java ilə birləşdirir.

Əsas məqamlar

  • NDK — C/C++ kodunu Android üçün yerli kitabxanalara kompilə etmək üçün alətlər dəsti.
  • JNI — Java/Kotlin virtual maşını ilə yerli kod arasında qarşılıqlı əlaqə interfeysi.
  • CMake — CMakeLists.txt vasitəsilə konfiqurasiya edilən NDK layihələri üçün əsas quruluş sistemi.
  • ABI — kitabxananın yığıldığı hədəf prosessor arxitekturası (arm64-v8a, armeabi-v7a, x86_64).
  • NDK əksər Android proqramları üçün lazım deyil və yalnız yüksək performans tələb edən tapşırıqlarda tətbiq olunur.

NDK nədir

NDK (Native Development Kit) — C və C++ kodunu Android üçün icra edilə bilən kitabxanalara çarpaz kompilə etmək üçün alətlər dəstidir. NDK-ya Clang kompilyatoru, libc++ standart kitabxanası, Android API başlıq faylları və quruluş yardımçı proqramları daxildir. Tərtibatçı C və ya C++ dilində yerli kod yazır, onu .so fayllarına (paylaşılan obyektlər) kompilə edir və JNI vasitəsilə proqrama qoşur.

NDK Android SDK-nı əvəz etmir, onu tamamlayır. Bütün UI, lifecycle və sistem xidmətləri Kotlin və ya Java dilində qalır. Yerli kod dar tapşırıqları həll edir: riyazi hesablamalar, kriptoqrafiya, kodeklər, oyunlarda fizika. Google tövsiyə edir NDK-dən yalnız SDK lazımi performansı və ya aparat imkanlarına girişi təmin etmədikdə istifadə etməyi.

NDK-nın tarixi 2009-cu ildən (NDK r1) başlayır. Bu müddət ərzində alətlər eksperimental skriptlər dəstindən CMake, LLDB debug və profilinq dəstəyi olan yetkin bir sistemə qədər inkişaf etmişdir. 2026-cı ilə olan aktual versiya — NDK r27 Clang 19, C++20-nin tam dəstəyi və yeganə standart kitabxana kimi libc++ ilə.

NDK-nın əsas imkanları

NDK tərtibatçıya yerli API-lər vasitəsilə Android-in aşağı səviyyəli imkanlarına giriş verir. Əsas istifadə ssenarilərinə daxildir: 3D qrafika üçün OpenGL ES və Vulkan ilə iş, Oboe vasitəsilə audio emalı, BoringSSL vasitəsilə kriptoqrafik əməliyyatlar və ARM üçün NEON optimallaşdırmaları. Bütün bu API-lər C/C++ dilindən əlçatandır və kompilə üçün NDK tələb edir.

Bundan əlavə, NDK mövcud C/C++ kitabxanalarını Kotlin dilinə yenidən yazmadan təkrar istifadə etməyə imkan verir. Bu, xüsusilə C++ dilində uzun illik tarixi olan layihələr üçün aktualdır — oyun mühərrikləri (Unity, Unreal Engine), kompüter görmə kitabxanaları (OpenCV) və ya kriptoqrafik paketlər (OpenSSL). Belə hallarda NDK illərlə inkişaf vaxtına qənaət edir.

KomponentTəyinat
ClangC++20 dəstəyi ilə C/C++ kompilyatoru
libc++Standart C++ kitabxanası (NDK r27-də yeganə)
CMakeYerli kitabxanaların quruluş sistemi
LLDBAndroid Studio-da yerli kod üçün debugger
ndk-buildKöhnəlmiş quruluş sistemi (CMake ilə əvəz olunub)

NDK vs SDK: yerli kod nə vaxt lazımdır

NDK ilə təmiz SDK arasında seçim tapşırıqdan asılıdır. Android SDK ssenarilərin 90%-i üçün hazır Java/Kotlin API-ləri təmin edir — şəbəkə, fayllar, bildirişlər, kamera ilə iş. NDK bu API-lər lazımi performansı və ya funksionallığı təmin etmədikdə qoşulur. Məsələn, real vaxtda audio emalı SDK vasitəsilə mümkündür, lakin 50–200 ms gecikmə ilə, halbuki Oboe vasitəsilə yerli kitabxana gecikməni 5–15 ms-ə endirir.

APK ölçüsü — başqa bir amil. NDK əlavə etmək proqramın ölçüsünü artırır, çünki hər bir ABI arxitekturası ayrıca .so kitabxanası tələb edir. Lakin Android App Bundle (AAB) istifadəsi problemi yumşaldır: Google Play istifadəçiyə yalnız onun arxitekturası üçün kitabxana çatdırır. Tipik bir yerli layihə qurğuda quraşdırma ölçüsünə 1–10 MB əlavə edir.

SDK və NDK-nın meyarlara görə müqayisəsi

MeyarSDK (Kotlin/Java)NDK (C/C++)
PerformansOrta (JIT/AOT kompilə)Yüksək (maşın kodu)
Audio gecikməsi50–200 ms5–15 ms Oboe vasitəsilə
3D qrafikaCanvas/OpenGL Kotlin API vasitəsiləBirbaşa Vulkan/OpenGL
İnkişaf mürəkkəbliyiAşağıYüksək (yaddaş idarəetməsi, JNI)
Kodun daşınmasıYalnız AndroidLinux, Windows, macOS, iOS
APK ölçüsüMinimal+1–10 MB kitabxana başına

NDK arxitekturası: alətlər və kitabxanalar

NDK Android SDK-dan ayrı olaraq SDK Manager vasitəsilə quraşdırılır. NDK kataloqu daxilində toolchain (kompilyatorlar), platforma kitabxanaları, başlıq faylları və yardımçı proqramlar yerləşir. NDK Toolchain bütün hədəf ABI-lər üçün çarpaz kompilə üçün Clang daxildir: arm64-v8a, armeabi-v7a, x86_64 və x86. Kompilyator CMake və ya ndk-build bayraqları əsasında avtomatik olaraq lazımi arxitekturanı seçir.

Yerli kod üçün Android API-lər sysroot/usr/include kataloqundakı başlıq faylları ilə təmsil olunur. Orada yerli koda açıq olan bütün API-lərin bəyannamələri yerləşir: Activity lifecycle üçün native_activity.h, giriş hadisələri üçün input.h, sensorlar üçün sensor.h. Bu başlıqların qoşulması JNI təbəqəsi olmadan aparat imkanlarına giriş verir.

NDK kataloq strukturu

text
ndk/
  toolchains/
    llvm/prebuilt/windows-x86_64/
      bin/        // Clang, ld, llvm-profdata
      sysroot/    // Android API başlıq faylları
  platforms/
    android-26/  // libc, libm, libdl API 26 üçün
    android-34/
  sources/
    cxx-stl/     // libc++ başlıqları
  build/
    cmake/       // CMake toolchain faylı

Android yerli API-ləri

NDK vasitəsilə aşağıdakı yerli API qrupları əlçatandır: Native App Glue (C dilindən Activity lifecycle idarəetməsi), OpenGL ES 3.2 və Vulkan 1.3 (qrafika), Oboe (aşağı gecikməli audio), Neural Networks API (qurğuda maşın öyrənməsi). Hər bir API-nin NDK tərkibində başlıq faylı və statik/dinamik kitabxanası var.

Yerli API-lərlə işləmək üçün JNI lazım deyil — funksiyalar birbaşa C/C++ kodundan çağırılır. Lakin Kotlin-də UI ilə qarşılıqlı əlaqə üçün yenə də JNI tələb olunur. Belə hibrid arxitektura oyun mühərriklərində rast gəlinir: qrafika və fizika C++ dilində (Vulkan vasitəsilə), menyu və UI Kotlin dilində (Jetpack Compose vasitəsilə).

JNI: Kotlin C++-ni necə çağırır

JNI (Java Native Interface) — Java/Kotlin virtual maşınından yerli kodun çağırılması üçün standart mexanizmdir. Tərtibatçı Kotlin-də external açar sözü ilə xarici funksiya elan edir və System.loadLibrary vasitəsilə .so kitabxanasını qoşur. C++ tərəfdə funksiya paketi və sinif adını kodlayan JNI adlandırma konvensiyası ilə elan edilir.

Kotlin-də yerli funksiyanın elanı

kotlin
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
}

// Kodda istifadə
val bridge = NativeBridge()
println(bridge.stringFromJNI())  // "Hello from C++"

C++ dilində JNI funksiyasının tətbiqi

cpp
#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;
}

NDK üçün CMakeLists.txt konfiqurasiyası

CMake — köhnəlmiş ndk-build-i əvəz edən NDK üçün əsas quruluş sistemidir. CMakeLists.txt faylı mənbə fayllarını, kitabxanaları və kompilə bayraqlarını təsvir edir. Android Studio build.gradle-da externalNativeBuild konfiqurasiya edildikdə layihə quruluşu zamanı CMake-i avtomatik çağırır. CMake hər bir hədəf ABI üçün make faylları generatesiya edir və yerli kodu paralel olaraq kompilə edir.

Yerli kitabxana üçün CMakeLists.txt nümunəsi

cmake
cmake_minimum_required(VERSION 3.22.1)
project("nativelib")

# Başlıq fayllarının qoşulması
include_directories(src/main/cpp/include)

# Yerli kitabxananın yaradılması
add_library(
    native-lib
    SHARED
    src/main/cpp/native-lib.cpp
    src/main/cpp/math_utils.cpp
    src/main/cpp/audio_processor.cpp
)

# Android sistem kitabxanalarının qoşulması
target_link_libraries(
    native-lib
    android
    log
    OpenSLES
    # libc++ avtomatik qoşulur
)

# Optimallaşdırma bayraqları
target_compile_options(native-lib PRIVATE -O3 -Wall -Wextra)

NDK üçün build.gradle konfiqurasiyası

groovy
android {
    defaultConfig {
        ndk {
            // Quruluş üçün hədəf ABI-lər
            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 və çoxplatformalı quruluş

ABI (Application Binary Interface) — cihazın prosessoru ilə uyğunluğu müəyyən edən maşın kodu formatıdır. Hər bir ARM və ya x86 arxitekturasının öz ABI-si var. NDK yerli kodu göstərilən hər bir ABI üçün ayrıca kompilə edir. 2026-cı ilə ən geniş yayılmış ABI-lər: arm64-v8a (müasir cihazların 99%-i), armeabi-v7a (köhnə 32-bit cihazlar), x86_64 (emulator və Chromebook).

build.gradle-da abiFilters göstərilməsi quruluşu yalnız lazımi arxitekturalarla məhdudlaşdırır, bu da kompilə vaxtını qısaldır. Google Play üçün kitabxananın uyğun olduğu bütün ABI-ləri daxil etmək tövsiyə olunur — bu, bütün cihazlarda işləməyi təmin edir. Google Play Console App Bundle vasitəsilə ABI-spesifik APK çatdırılmasını konfiqurasiya etməyə imkan verir.

Yerli kodda cihazın ABI-sinin təyini

cpp
#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");
}
ABIArxitekturaBit ölçüsüCihazlar
arm64-v8aARMv8-A64-bitDemək olar ki, bütün müasir telefonlar
armeabi-v7aARMv7-A32-bitKöhnə cihazlar (2020-ci ilə qədər)
x86_64x86-6464-bitEmulator, Chromebook
x86x86 IA-3232-bitKöhnəlmiş emulatorlar

C++ dilində yerli kod nümunələri

Praktik bir nümunəyə baxaq: üzən nöqtəli ədədlərlə iş üçün riyazi kitabxana. C++ dilində yerli kod NEON ARM təlimatlarına birbaşa giriş və runtime-da massiv sərhədlərinin yoxlanılmasının olmaması sayəsində Kotlin-dən daha səmərəli hesablamalar aparır. Bu nümunə NDK istifadəsinin tipik nümunəsini — ağır hesablamaların yerli təbəqəyə çıxarılmasını nümayiş etdirir.

Yerli kodda riyazi əməliyyatlar

cpp
#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);

    // Orta və standart kənarlaşmanı hesablayırıq
    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);

    // Normalizasiya: (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;
}

Yerli koddan loglama

Yerli kodun debug edilməsi üçün android/log.h kitabxanasından __android_log_print makrosundan istifadə edin. Mesajlar Logcat-də Java/Kotlin loqları ilə yanaşı görünür. Loglama səviyyəsi (ANDROID_LOG_DEBUG, ANDROID_LOG_ERROR) mesajları filtrləməyə kömək edir.

cpp
#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++) {
        // Ağır emal
        LOGD("Item %d processed", i);
    }

    LOGD("Processing complete");
}

Tez-tez verilən suallar

Android inkişafı üçün NDK istifadəsi məcburidirmi?

Xeyr. Əksər proqramlar üçün Kotlin dilində SDK kifayətdir. NDK lazımdır yüksək performanslı tapşırıqlar üçün: real vaxtda audio/video emalı, 3D qrafika, kriptoqrafiya və ya mövcud C/C++ layihələrinin təkrar istifadəsi.

NDK hansı kompilyatordan istifadə edir?

NDK LLVM toolchain-dən Clang istifadə edir. NDK r23-dən etibarən GCC tamamilə silinmişdir. Clang bütün Android ABI-ləri üçün kodu çarpaz kompilə edir: arm64-v8a, armeabi-v7a, x86_64, x86.

NDK kontekstində ABI nədir?

ABI (Application Binary Interface) — prosessorla uyğunluğu müəyyən edən maşın kodu formatıdır. NDK .so kitabxanalarını hər bir ABI üçün ayrıca yığır. arm64-v8a — müasir Android cihazları üçün əsas ABI.

C++ kodunu NDK vasitəsilə debug etmək olarmı?

Bəli. Android Studio LLDB — yerli kod debuggerini dəstəkləyir. C++ fayllarında breakpointlər qoymaq, dəyişənlərə və çağırış stackinə baxmaq olar. İş üçün NDK və LLDB plagini tələb olunur.

NDK APK ölçüsünə necə təsir edir?

Hər bir yerli kitabxana APK-ya 100 KB — bir neçə MB əlavə edir. Hər bir ABI üçün ayrıca .so kitabxanası lazımdır. Android App Bundle istifadəçiyə yalnız uyğun arxitekturanı çatdırır, quraşdırma ölçüsünü azaldır.

Nəticə

  • NDK — Clang kompilyatoru vasitəsilə C/C++ kodunu Android üçün yerli kitabxanalara çarpaz kompilə etmək üçün alətlər dəsti.
  • JNI — Kotlin/Java-nı yerli kodla external açar sözü və funksiya adlandırma konvensiyası vasitəsilə birləşdirən interfeys.
  • CMake — CMakeLists.txt faylı və Gradle-da externalNativeBuild vasitəsilə konfiqurasiya edilən NDK-nın əsas quruluş sistemi.
  • ABI prosessor arxitekturasını təyin edir — arm64-v8a, armeabi-v7a, x86_64. Hər bir ABI kitabxananın ayrıca yığılmasını tələb edir.
  • NDK-dən yalnız yüksək performans tələb edən tapşırıqlar üçün istifadə edin: oyunlar, audio, qrafika, kriptoqrafiya, qurğuda maşın öyrənməsi.
  • Google Play App Bundle vasitəsilə ABI bölgüsünü dəstəkləyir: istifadəçi yalnız öz cihazının arxitekturası üçün kitabxana alır.
  • Yerli kitabxanalar APK-nı əhəmiyyətli dərəcədə artırır, lakin kritik əməliyyatlar üçün maksimum performans və aşağı gecikmə təmin edir.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun