NDK Android: apa itu, Native Development Kit dan JNI untuk C++

Penulis: IT Sectr Diterbitkan: 2026-02-09 Waktu membaca: 10 mnt

NDK (Native Development Kit) — adalah seperangkat alat untuk menulis bagian aplikasi dalam C dan C++ untuk Android. Tidak seperti Android SDK biasa, NDK mengompilasi kode menjadi pustaka asli (.so) yang bekerja langsung pada prosesor tanpa lapisan mesin virtual. Menurut Google NDK Guides, 2026, NDK digunakan untuk komputasi berkinerja tinggi, game, pemrosesan audio, dan penggunaan kembali proyek C/C++ yang ada. JNI (Java Native Interface) menghubungkan kode asli dengan Kotlin dan Java.

Poin Utama

  • NDK — seperangkat alat untuk mengompilasi kode C/C++ menjadi pustaka asli untuk Android.
  • JNI — antarmuka interaksi antara mesin virtual Java/Kotlin dan kode asli.
  • CMake — sistem build utama untuk proyek NDK, dikonfigurasi melalui CMakeLists.txt.
  • ABI — arsitektur prosesor target (arm64-v8a, armeabi-v7a, x86_64) tempat pustaka dibangun.
  • NDK tidak diperlukan untuk sebagian besar aplikasi Android dan hanya digunakan dalam tugas dengan kebutuhan kinerja tinggi.

Apa itu NDK

NDK (Native Development Kit) — adalah seperangkat alat untuk kompilasi silang kode C dan C++ menjadi pustaka yang dapat dieksekusi untuk Android. NDK mencakup compiler Clang, pustaka standar libc++, file header Android API, dan utilitas build. Pengembang menulis kode asli dalam C atau C++, mengompilasinya ke file .so (shared objects), dan menghubungkannya ke aplikasi melalui JNI.

NDK tidak menggantikan Android SDK, tetapi melengkapinya. Seluruh UI, lifecycle, dan layanan sistem tetap di Kotlin atau Java. Kode asli menyelesaikan tugas-tugas spesifik: perhitungan matematika, kriptografi, codec, fisika dalam game. Google merekomendasikan menggunakan NDK hanya ketika SDK tidak memberikan kinerja yang diperlukan atau akses ke kemampuan perangkat keras.

Sejarah NDK dimulai pada tahun 2009 (NDK r1). Selama waktu ini, perangkat telah berkembang dari kumpulan skrip eksperimental menjadi sistem yang matang dengan dukungan CMake, debugging LLDB, dan profiling. Pada tahun 2026, versi saat ini adalah NDK r27 dengan Clang 19, dukungan penuh C++20 dan libc++ sebagai satu-satunya pustaka standar.

Kemampuan utama NDK

NDK memberikan akses pengembang ke kemampuan tingkat rendah Android melalui API asli. Skenario penggunaan utama meliputi: bekerja dengan OpenGL ES dan Vulkan untuk grafis 3D, pemrosesan audio melalui Oboe, operasi kriptografi melalui BoringSSL, dan optimasi NEON untuk ARM. Semua API ini dapat diakses dari C/C++ dan memerlukan NDK untuk kompilasi.

Selain itu, NDK memungkinkan penggunaan kembali pustaka C/C++ yang ada tanpa menulis ulang ke Kotlin. Ini sangat relevan untuk proyek dengan sejarah panjang di C++ — mesin game (Unity, Unreal Engine), pustaka computer vision (OpenCV), atau paket kriptografi (OpenSSL). Dalam kasus seperti itu, NDK menghemat waktu pengembangan bertahun-tahun.

KomponenTujuan
ClangCompiler C/C++ dengan dukungan C++20
libc++Pustaka standar C++ (satu-satunya di NDK r27)
CMakeSistem build pustaka asli
LLDBDebugger kode asli di Android Studio
ndk-buildSistem build usang (digantikan oleh CMake)

NDK vs SDK: kapan kode asli diperlukan

Pilihan antara NDK dan SDK murni tergantung pada tugas. Android SDK menyediakan API Java/Kotlin siap pakai untuk 90% skenario — bekerja dengan jaringan, file, notifikasi, kamera. NDK dihubungkan ketika API ini tidak memberikan kinerja atau fungsionalitas yang diperlukan. Misalnya, pemrosesan audio real-time melalui SDK dimungkinkan, tetapi dengan latensi 50–200 ms, sementara pustaka asli melalui Oboe mengurangi latensi menjadi 5–15 ms.

Ukuran APK — faktor lain. Penambahan NDK meningkatkan ukuran aplikasi, karena setiap arsitektur ABI memerlukan pustaka .so terpisah. Namun, penggunaan Android App Bundle (AAB) mengurangi masalah: Google Play mengirimkan ke pengguna hanya pustaka untuk arsitekturnya. Proyek asli tipikal menambahkan 1–10 MB ke ukuran instalasi di perangkat.

Perbandingan SDK dan NDK berdasarkan kriteria

KriteriaSDK (Kotlin/Java)NDK (C/C++)
KinerjaSedang (kompilasi JIT/AOT)Tinggi (kode mesin)
Latensi audio50–200 ms5–15 ms melalui Oboe
Grafis 3DMelalui Canvas/OpenGL Kotlin APIVulkan/OpenGL langsung
Kompleksitas pengembanganRendahTinggi (manajemen memori, JNI)
Portabilitas kodeHanya AndroidLinux, Windows, macOS, iOS
Ukuran APKMinimal+1–10 MB per pustaka

Arsitektur NDK: alat dan pustaka

NDK diinstal terpisah dari Android SDK melalui SDK Manager. Di dalam direktori NDK terdapat toolchain (compiler), pustaka platform, file header, dan utilitas. Toolchain NDK mencakup Clang untuk kompilasi silang ke semua ABI target: arm64-v8a, armeabi-v7a, x86_64, dan x86. Compiler secara otomatis memilih arsitektur yang tepat berdasarkan flag CMake atau ndk-build.

API Android untuk kode asli diwakili oleh file header di direktori sysroot/usr/include. Di sana terdapat deklarasi untuk semua API yang tersedia dalam kode asli: native_activity.h untuk lifecycle Activity, input.h untuk event input, sensor.h untuk sensor. Menghubungkan header ini memberikan akses ke kemampuan perangkat keras tanpa lapisan JNI.

Struktur direktori NDK

text
ndk/
  toolchains/
    llvm/prebuilt/windows-x86_64/
      bin/        // Clang, ld, llvm-profdata
      sysroot/    // File header Android API
  platforms/
    android-26/  // libc, libm, libdl untuk API 26
    android-34/
  sources/
    cxx-stl/     // Header libc++
  build/
    cmake/       // File toolchain CMake

API asli Android

Melalui NDK, kelompok API asli berikut tersedia: Native App Glue (manajemen lifecycle Activity dari C), OpenGL ES 3.2 dan Vulkan 1.3 (grafis), Oboe (audio latensi rendah), Neural Networks API (pembelajaran mesin di perangkat). Setiap API memiliki file header dan pustaka statis/dinamis dalam komposisi NDK.

Untuk bekerja dengan API asli, JNI tidak diperlukan — fungsi dipanggil langsung dari kode C/C++. Namun, untuk interaksi dengan UI di Kotlin, JNI tetap diperlukan. Arsitektur hibrida seperti ini ditemukan di mesin game: grafis dan fisika di C++ (melalui Vulkan), menu dan UI di Kotlin (melalui Jetpack Compose).

JNI: bagaimana Kotlin memanggil C++

JNI (Java Native Interface) — mekanisme standar untuk memanggil kode asli dari mesin virtual Java/Kotlin. Pengembang mendeklarasikan di Kotlin fungsi eksternal dengan kata kunci external dan menghubungkan pustaka .so melalui System.loadLibrary. Di sisi C++, fungsi dideklarasikan menggunakan konvensi penamaan JNI yang mengkodekan paket dan nama kelas.

Deklarasi fungsi asli di Kotlin

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
}

// Penggunaan dalam kode
val bridge = NativeBridge()
println(bridge.stringFromJNI())  // "Hello from C++"

Implementasi fungsi JNI di C++

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

Konfigurasi CMakeLists.txt untuk NDK

CMake — sistem build utama untuk NDK, yang menggantikan ndk-build usang. File CMakeLists.txt mendeskripsikan file sumber, pustaka, dan flag kompilasi. Android Studio secara otomatis memanggil CMake saat membangun proyek jika externalNativeBuild dikonfigurasi di build.gradle. CMake menghasilkan file make untuk setiap ABI target dan mengompilasi kode asli secara paralel.

Contoh CMakeLists.txt untuk pustaka asli

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

# Menghubungkan file header
include_directories(src/main/cpp/include)

# Membuat pustaka asli
add_library(
    native-lib
    SHARED
    src/main/cpp/native-lib.cpp
    src/main/cpp/math_utils.cpp
    src/main/cpp/audio_processor.cpp
)

# Menghubungkan pustaka sistem Android
target_link_libraries(
    native-lib
    android
    log
    OpenSLES
    # libc++ terhubung secara otomatis
)

# Flag optimasi
target_compile_options(native-lib PRIVATE -O3 -Wall -Wextra)

Konfigurasi build.gradle untuk NDK

groovy
android {
    defaultConfig {
        ndk {
            // ABI target untuk build
            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 dan build multi-platform

ABI (Application Binary Interface) — adalah format kode mesin yang menentukan kompatibilitas dengan prosesor perangkat. Setiap arsitektur ARM atau x86 memiliki ABI sendiri. NDK mengompilasi kode asli secara terpisah untuk setiap ABI yang ditentukan. ABI yang paling umum pada tahun 2026: arm64-v8a (99% perangkat modern), armeabi-v7a (perangkat 32-bit lama), x86_64 (emulator dan Chromebook).

Menentukan abiFilters di build.gradle membatasi build hanya pada arsitektur yang diperlukan, yang mempercepat waktu kompilasi. Untuk Google Play, disarankan untuk menyertakan semua ABI yang kompatibel dengan pustaka — ini menjamin kerja di semua perangkat. Google Play Console memungkinkan konfigurasi pengiriman APK spesifik ABI melalui App Bundle.

Menentukan ABI perangkat dalam kode asli

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");
}
ABIArsitekturBitPerangkat
arm64-v8aARMv8-A64-bitHampir semua ponsel modern
armeabi-v7aARMv7-A32-bitPerangkat lama (hingga 2020)
x86_64x86-6464-bitEmulator, Chromebook
x86x86 IA-3232-bitEmulator usang

Contoh kode asli dalam C++

Mari kita lihat contoh praktis: pustaka matematika untuk bekerja dengan angka floating-point. Kode asli di C++ melakukan perhitungan lebih efisien daripada Kotlin, berkat akses langsung ke instruksi NEON ARM dan tidak adanya pemeriksaan batas array di runtime. Contoh ini menunjukkan pola khas penggunaan NDK — memindahkan perhitungan berat ke lapisan asli.

Operasi matematika dalam kode asli

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

    // Menghitung rata-rata dan deviasi standar
    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);

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

Logging dari kode asli

Untuk debugging kode asli, gunakan makro __android_log_print dari pustaka android/log.h. Pesan muncul di Logcat di samping log Java/Kotlin. Level logging (ANDROID_LOG_DEBUG, ANDROID_LOG_ERROR) membantu memfilter pesan.

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++) {
        // Pemrosesan berat
        LOGD("Item %d processed", i);
    }

    LOGD("Processing complete");
}

Pertanyaan Umum

Apakah wajib menggunakan NDK untuk pengembangan Android?

Tidak. Untuk sebagian besar aplikasi, SDK di Kotlin sudah cukup. NDK diperlukan untuk tugas berkinerja tinggi: pemrosesan audio/video real-time, grafis 3D, kriptografi, atau penggunaan kembali proyek C/C++ yang ada.

Compiler apa yang digunakan NDK?

NDK menggunakan Clang dari LLVM toolchain. Mulai NDK r23, GCC sepenuhnya dihapus. Clang melakukan kompilasi silang kode untuk semua ABI Android: arm64-v8a, armeabi-v7a, x86_64, x86.

Apa itu ABI dalam konteks NDK?

ABI (Application Binary Interface) — format kode mesin yang menentukan kompatibilitas dengan prosesor. NDK membangun pustaka .so untuk setiap ABI secara terpisah. arm64-v8a — ABI utama untuk perangkat Android modern.

Bisakah kode C++ di-debug melalui NDK?

Ya. Android Studio mendukung LLDB — debugger kode asli. Anda dapat menempatkan breakpoint di file C++, melihat variabel dan stack panggilan. Untuk bekerja, diperlukan NDK dan plugin LLDB.

Bagaimana NDK mempengaruhi ukuran APK?

Setiap pustaka asli menambahkan 100 KB — beberapa MB ke APK. Untuk setiap ABI, diperlukan pustaka .so terpisah. Android App Bundle mengirimkan ke pengguna hanya arsitektur yang sesuai, mengurangi ukuran instalasi.

Kesimpulan

  • NDK — seperangkat alat untuk kompilasi silang kode C/C++ menjadi pustaka asli untuk Android melalui compiler Clang.
  • JNI — antarmuka yang menghubungkan Kotlin/Java dengan kode asli melalui kata kunci external dan konvensi penamaan fungsi.
  • CMake — sistem build utama NDK, dikonfigurasi melalui file CMakeLists.txt dan externalNativeBuild di Gradle.
  • ABI menentukan arsitektur prosesor — arm64-v8a, armeabi-v7a, x86_64. Setiap ABI memerlukan build pustaka terpisah.
  • Gunakan NDK hanya untuk tugas yang membutuhkan kinerja tinggi: game, audio, grafis, kriptografi, pembelajaran mesin di perangkat.
  • Google Play mendukung pemisahan ABI melalui App Bundle: pengguna hanya menerima pustaka untuk arsitektur perangkatnya.
  • Pustaka asli secara signifikan meningkatkan APK, tetapi memberikan kinerja maksimal dan latensi rendah untuk operasi kritis.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga