跪拜 Guibai
← All articles
Android

The Android Terminology Tangle: SDK, NDK, Framework, and Native Are Not on the Same Axis

By 爱笑鱼 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Mislabeling a crash as an NDK problem when it is a system native daemon failure, or treating the SDK as the runtime Framework, sends debugging in the wrong direction and wastes hours. The distinction determines whether you reach for Gradle configs, JNI bindings, system_server traces, or HAL/vendor tombstones.

Summary

Android's core terminology mixes four distinct dimensions: development toolkits (SDK, NDK), delivery units (APP), system layers (Framework, Native), and runtime implementations (Java/Kotlin, C/C++, JNI). Calling the SDK the Framework, or the NDK the Native layer, creates confusion that breaks down during debugging. A native crash in an app's .so is not a system native layer problem; using the NDK does not mean you are doing AOSP-level native development.

The SDK is a compile-time API contract and toolset; the Framework is the runtime implementation spread across system_server, Binder, and native services. The NDK compiles C/C++ into app-native libraries that still run inside the app sandbox, not as system daemons. An APP remains an APP regardless of whether it contains .so files, because its identity is defined by its package, UID, permissions, and sandbox, not its implementation language.

A practical decision tree separates issues into five categories: SDK/build-tool problems, NDK/ABI/JNI problems, app runtime identity problems, Framework/system_server problems, and system native/HAL problems. The key is always asking whether you are looking at a toolkit, a deliverable, or a runtime layer before assigning blame.

Takeaways
SDK and NDK are development toolkits, not system runtime layers.
An APP is defined by its package, UID, sandbox, and manifest — not by whether it contains Kotlin, Java, or C++ .so files.
The Framework is the runtime implementation of system capabilities, not the compile-time android.jar.
Native has at least five distinct meanings: language-level native code, the Java native keyword, app-native .so libraries, system native daemons/services, and product-form native apps.
A native crash in /data/app belongs to the app; a native crash in /system/bin or /vendor/bin belongs to the platform.
Using the NDK produces app-native libraries that still run inside the app sandbox; it does not turn an app into a system native module.
Framework code crosses into native via JNI, so labeling Framework as Java and Native as C++ is too coarse.
Troubleshooting should first classify the issue as a toolchain, ABI, app-identity, Framework, or system-native problem.
Conclusions

The confusion is structural, not accidental: Android's documentation and tooling names reuse the word native across toolkits, language keywords, system layers, and product categories without disambiguation.

Treating android.jar as the Framework is a category error that persists because compile-time API surfaces and runtime implementations share class names but live in entirely different processes and trust boundaries.

The NDK's name invites the misconception that it targets the system native layer, when its actual scope is app-local native libraries — a much narrower and sandboxed role.

A practical litmus test for any Android term is asking whether it describes a toolkit, a deliverable, a system layer, or a runtime implementation; most confusion collapses once the dimension is identified.

Concepts & terms
SDK (Software Development Kit)
A set of tools, API declarations (android.jar), build utilities, and platform tools that let developers compile, debug, and package Android apps. It is a compile-time contract, not the runtime implementation.
NDK (Native Development Kit)
A toolchain (Clang/LLVM, headers, CMake integration) for compiling C/C++ code into .so libraries that ship inside an APK. It targets app-native code, not the Android system native layer.
Framework (Android)
The system layer that abstracts hardware and low-level services into APIs. It spans Java code in frameworks/base, system services in system_server, Binder IPC, and JNI bridges into native code.
Native (in Android contexts)
A context-dependent term that can mean C/C++ code, the Java native keyword, an app's .so library, a system daemon like surfaceflinger, or a platform-native app. Disambiguation requires checking the process, file path, and module.
JNI (Java Native Interface)
The bridge that allows Java/Kotlin code to call C/C++ functions and vice versa. It is the mechanism behind the native keyword in Java and the loading of .so files in Android apps.
system_server
A core Android process that hosts most Framework system services (ActivityManagerService, PackageManagerService, etc.). It is a key runtime component of the Framework layer, distinct from app processes.
From the discussion
Featured comments
丨小夕

Explained very clearly [thumbs up]. I think a program only needs two core concepts. 1: compile-time / run-time. The SDK is just what's publicly exposed for you to call; as long as the runtime exists, even without the SDK you can craft your own API to fool the compiler, or use reflection to call it successfully. 2: in-process or out-of-process. Inside the process, the entire memory is visible to you, theoretically nothing can stop you. Framework code in Android, however, is loaded into your process.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗