NDK (Native Development Kit) — ay isang toolkit para sa pagsulat ng bahagi ng aplikasyon sa C at C++ para sa Android. Hindi tulad ng karaniwang Android SDK, ang NDK ay nagco-compile ng code sa native na mga library (.so) na direktang gumagana sa processor nang walang layer ng virtual machine. Ayon sa Google NDK Guides, 2026, ang NDK ay ginagamit para sa high-performance computing, laro, audio processing, at muling paggamit ng mga existing na C/C++ na proyekto. JNI (Java Native Interface) ay nag-uugnay ng native code sa Kotlin at Java.
Mga Pangunahing Punto
NDK (Native Development Kit) — ay isang set ng mga tool para sa cross-compiling ng C at C++ code sa mga executable library para sa Android. Kasama sa NDK ang Clang compiler, libc++ standard library, Android API header files, at build utilities. Ang developer ay sumusulat ng native code sa C o C++, ini-compile ito sa .so files (shared objects), at ikinokonekta ito sa app sa pamamagitan ng JNI.
Hindi pinapalitan ng NDK ang Android SDK, kundi pinupunan ito. Ang buong UI, lifecycle, at system services ay nananatili sa Kotlin o Java. Ang native code ay lumulutas ng mga tiyak na gawain: mathematical computations, cryptography, codec, physics sa mga laro. Inirerekomenda ng Google na gamitin lamang ang NDK kapag hindi ibinibigay ng SDK ang kinakailangang performance o access sa hardware capabilities.
Ang kasaysayan ng NDK ay nagsimula noong 2009 (NDK r1). Sa panahong ito, ang mga tool ay umunlad mula sa isang experimental na set ng scripts tungo sa isang mature system na may suporta sa CMake, LLDB debugging, at profiling. Noong 2026, ang kasalukuyang bersyon ay NDK r27 na may Clang 19, buong suporta sa C++20 at libc++ bilang tanging standard library.
Ang NDK ay nagbibigay sa developer ng access sa low-level na kakayahan ng Android sa pamamagitan ng native APIs. Ang mga pangunahing senaryo ng paggamit ay kinabibilangan ng: pagtatrabaho sa OpenGL ES at Vulkan para sa 3D graphics, audio processing sa pamamagitan ng Oboe, cryptographic operations sa pamamagitan ng BoringSSL at NEON optimizations para sa ARM. Lahat ng APIs na ito ay accessible mula sa C/C++ at nangangailangan ng NDK para sa compilation.
Bukod dito, pinapayagan ng NDK ang muling paggamit ng mga existing na C/C++ library nang hindi kinakailangang isulat muli sa Kotlin. Ito ay partikular na mahalaga para sa mga proyektong may mahabang kasaysayan sa C++ — game engines (Unity, Unreal Engine), computer vision libraries (OpenCV), o cryptographic packages (OpenSSL). Sa ganitong mga kaso, ang NDK ay nakakatipid ng mga taon ng development.
| Component | Layunin |
|---|---|
| Clang | C/C++ compiler na may suporta sa C++20 |
| libc++ | Standard C++ library (tangi sa NDK r27) |
| CMake | Build system para sa native na mga library |
| LLDB | Native code debugger sa Android Studio |
| ndk-build | Lumang build system (pinalitan ng CMake) |
Ang pagpili sa pagitan ng NDK at purong SDK ay depende sa gawain. Ang Android SDK ay nagbibigay ng mga handa na Java/Kotlin API para sa 90% ng mga senaryo — pagtatrabaho sa network, file, notification, camera. Ang NDK ay ikinokonekta kapag ang mga API na ito ay hindi nagbibigay ng kinakailangang performance o functionality. Halimbawa, ang real-time audio processing sa pamamagitan ng SDK ay posible, ngunit may latency na 50–200 ms, habang ang native library sa pamamagitan ng Oboe ay nagbabawas ng latency sa 5–15 ms.
Laki ng APK — isa pang factor. Ang pagdaragdag ng NDK ay nagpapalaki ng app, dahil ang bawat ABI architecture ay nangangailangan ng hiwalay na .so library. Gayunpaman, ang paggamit ng Android App Bundle (AAB) ay nagpapagaan ng problema: ang Google Play ay nagde-deliver sa user ng library lamang para sa kanyang architecture. Ang isang tipikal na native project ay nagdaragdag ng 1–10 MB sa laki ng installation sa device.
| Criteria | SDK (Kotlin/Java) | NDK (C/C++) |
|---|---|---|
| Performance | Katamtaman (JIT/AOT compilation) | Mataas (machine code) |
| Audio latency | 50–200 ms | 5–15 ms sa pamamagitan ng Oboe |
| 3D graphics | Sa pamamagitan ng Canvas/OpenGL Kotlin API | Direktang Vulkan/OpenGL |
| Pagiging kumplikado ng development | Mababa | Mataas (memory management, JNI) |
| Portability ng code | Android lamang | Linux, Windows, macOS, iOS |
| Laki ng APK | Minimal | +1–10 MB bawat library |
Ang NDK ay ini-install nang hiwalay mula sa Android SDK sa pamamagitan ng SDK Manager. Sa loob ng NDK directory ay matatagpuan ang toolchain (compilers), platform libraries, header files, at utilities. NDK Toolchain ay may kasamang Clang para sa cross-compilation para sa lahat ng target na ABI: arm64-v8a, armeabi-v7a, x86_64 at x86. Ang compiler ay awtomatikong pumipili ng tamang architecture batay sa CMake o ndk-build flags.
Ang Android API para sa native code ay kinakatawan ng header files sa directory na sysroot/usr/include. Doon matatagpuan ang mga deklarasyon para sa lahat ng API na available sa native code: native_activity.h para sa Activity lifecycle, input.h para sa input events, sensor.h para sa sensors. Ang pagkonekta ng mga header na ito ay nagbibigay ng access sa hardware capabilities nang walang JNI layer.
ndk/
toolchains/
llvm/prebuilt/windows-x86_64/
bin/ // Clang, ld, llvm-profdata
sysroot/ // Android API header files
platforms/
android-26/ // libc, libm, libdl para sa API 26
android-34/
sources/
cxx-stl/ // libc++ headers
build/
cmake/ // CMake toolchain file
Sa pamamagitan ng NDK, ang mga sumusunod na grupo ng native APIs ay available: Native App Glue (pamamahala ng Activity lifecycle mula sa C), OpenGL ES 3.2 at Vulkan 1.3 (graphics), Oboe (low-latency audio), Neural Networks API (machine learning sa device). Bawat API ay may header file at static/dynamic library sa komposisyon ng NDK.
Para sa pagtatrabaho sa native APIs, hindi kailangan ang JNI — ang mga function ay direktang tinatawag mula sa C/C++ code. Gayunpaman, para sa interaksyon sa UI sa Kotlin, kinakailangan pa rin ang JNI. Ang ganitong hybrid architecture ay matatagpuan sa game engines: graphics at physics sa C++ (sa pamamagitan ng Vulkan), menu at UI sa Kotlin (sa pamamagitan ng Jetpack Compose).
JNI (Java Native Interface) — ang standard na mekanismo para sa pagtawag ng native code mula sa Java/Kotlin virtual machine. Ang developer ay nagdedeklara sa Kotlin ng external function na may keyword na external at kinokonekta ang .so library sa pamamagitan ng System.loadLibrary. Sa panig ng C++, ang function ay idinedeklara gamit ang JNI naming convention na nag-eencode ng package at pangalan ng klase.
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
}
// Paggamit sa code
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 — ang pangunahing build system para sa NDK, na pumalit sa lumang ndk-build. Ang file na CMakeLists.txt ay naglalarawan ng source files, library, at compilation flags. Ang Android Studio ay awtomatikong tumatawag ng CMake sa pag-build ng project kung ang externalNativeBuild ay na-configure sa build.gradle. Ang CMake ay gumagawa ng make files para sa bawat target na ABI at nagco-compile ng native code nang magkatulad.
cmake_minimum_required(VERSION 3.22.1)
project("nativelib")
# Pagkonekta ng header files
include_directories(src/main/cpp/include)
# Paglikha ng native library
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp
src/main/cpp/math_utils.cpp
src/main/cpp/audio_processor.cpp
)
# Pagkonekta ng Android system libraries
target_link_libraries(
native-lib
android
log
OpenSLES
# Ang libc++ ay awtomatikong kumokonekta
)
# Optimization flags
target_compile_options(native-lib PRIVATE -O3 -Wall -Wextra)
android {
defaultConfig {
ndk {
// Target na ABI para sa 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 (Application Binary Interface) — ay ang format ng machine code na tumutukoy sa compatibility sa processor ng device. Bawat ARM o x86 architecture ay may sariling ABI. Ang NDK ay nagco-compile ng native code nang hiwalay para sa bawat tinukoy na ABI. Ang pinakakaraniwang ABI noong 2026: arm64-v8a (99% ng modernong devices), armeabi-v7a (lumang 32-bit devices), x86_64 (emulator at Chromebook).
Ang pagtukoy ng abiFilters sa build.gradle ay naglilimita sa build sa mga kinakailangang architecture lamang, na nagpapabilis ng compilation time. Para sa Google Play, inirerekomenda na isama ang lahat ng ABI kung saan compatible ang library — ito ay garantiya ng paggana sa lahat ng device. Ang Google Play Console ay nagpapahintulot sa pag-configure ng ABI-specific APK delivery sa pamamagitan ng 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 | Arkitektura | Bit | Mga Device |
|---|---|---|---|
| arm64-v8a | ARMv8-A | 64-bit | Halos lahat ng modernong telepono |
| armeabi-v7a | ARMv7-A | 32-bit | Mga lumang device (hanggang 2020) |
| x86_64 | x86-64 | 64-bit | Emulator, Chromebook |
| x86 | x86 IA-32 | 32-bit | Mga lumang emulator |
Tingnan natin ang isang praktikal na halimbawa: isang mathematical library para sa pagtatrabaho sa floating-point numbers. Ang native code sa C++ ay mas mahusay na nagsasagawa ng computations kaysa Kotlin, dahil sa direktang access sa NEON ARM instructions at kawalan ng array bounds checking sa runtime. Ang halimbawang ito ay nagpapakita ng tipikal na pattern ng paggamit ng NDK — paglilipat ng mabibigat na computations sa native layer.
#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);
// Kinakalkula ang mean at standard deviation
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);
// Normalization: (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;
}
Para sa debugging ng native code, gamitin ang macro na __android_log_print mula sa library na android/log.h. Ang mga mensahe ay lilitaw sa Logcat kasama ng Java/Kotlin logs. Ang logging level (ANDROID_LOG_DEBUG, ANDROID_LOG_ERROR) ay tumutulong sa pag-filter ng mga mensahe.
#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++) {
// Mabigat na processing
LOGD("Item %d processed", i);
}
LOGD("Processing complete");
}
Mga Madalas na Itanong
Hindi. Para sa karamihan ng apps, sapat na ang SDK sa Kotlin. Kailangan ang NDK para sa mga gawaing may mataas na performance: real-time audio/video processing, 3D graphics, cryptography, o muling paggamit ng existing na C/C++ projects.
Ang NDK ay gumagamit ng Clang mula sa LLVM toolchain. Mula NDK r23, ang GCC ay ganap na inalis. Ang Clang ay nagco-cross-compile ng code para sa lahat ng Android ABI: arm64-v8a, armeabi-v7a, x86_64, x86.
ABI (Application Binary Interface) — format ng machine code na tumutukoy sa compatibility sa processor. Ang NDK ay bumubuo ng .so library para sa bawat ABI nang hiwalay. arm64-v8a — pangunahing ABI para sa modernong Android devices.
Oo. Ang Android Studio ay sumusuporta sa LLDB — native code debugger. Maaaring maglagay ng breakpoints sa C++ files, tingnan ang variables at call stack. Para sa paggana, kinakailangan ang NDK at LLDB plugin.
Bawat native library ay nagdaragdag ng 100 KB — ilang MB sa APK. Para sa bawat ABI, kinakailangan ang hiwalay na .so library. Ang Android App Bundle ay nagde-deliver sa user ng tamang architecture lamang, na nagbabawas sa laki ng installation.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din