NDK、SDK、APP、Framework、Native 到底怎么区分?
学 Android 时,很容易被几个词绕进去:SDK、NDK、APP、Framework、Native。
有时候你看到的是:
java
用 Android SDK 开发 App。
用 Android NDK 写 C/C++。
App 调 Framework API。
Framework 最后进 native service。
Java 里有 native 方法。
Native 崩溃了,看 tombstone。
每句话看起来都对,但放在一起就容易乱:
java
SDK 是不是 Framework?
NDK 是不是 Native 层?
用了 C++ 的 App,算不算 native App?
App 里的 .so 和系统里的 native service 是不是一回事?
Framework 是 Java 层,Native 是 C++ 层,这样理解够不够?
系统开发说的 native,和 Java 里的 native 关键字,是不是同一个概念?
这篇先把问题问清楚:这些词不是同一个维度上的概念。 
有些词描述的是开发工具包,比如 SDK、NDK。
有些词描述的是交付形态和运行身份,比如 APP。
有些词描述的是Android 系统分层,比如 Framework、Native、HAL、Kernel。
有些词描述的是代码语言或运行实现,比如 Java/Kotlin、C/C++、JNI、native 方法。
如果把这些维度混在一起,就会出现一种很典型的误解:以为用了 NDK 就是在做 Android Native 层开发;以为 SDK 就等于 Framework;以为 App 只要带了 .so 就变成系统 native 模块;以为 native 崩溃一定就是 NDK 问题。
先把结论放前面:
markdown
SDK:
Android 提供给开发者的工具包和 API 契约,主要用于编译、调试、打包、运行 Android 应用。
NDK:
Android 提供给开发者写 C/C++ 代码的 native 开发工具包,通常把 C/C++ 编译成 .so 放进 App。
APP:
交付给设备安装和运行的应用单位,表现为 APK/AAB,运行时是一个或多个进程,里面可以有 Java/Kotlin,也可以有 native .so。
Framework:
Android 系统向上提供能力的框架层,包括公开 API、系统 API、Framework Java 代码、system_server 中的系统服务等。
Native:
一个上下文相关的词。它可以表示 C/C++ 代码,可以表示系统 native 层的 daemon/library/service,也可以表示 Java native 方法背后的 JNI 实现。
真正要先问的是:
我现在讨论的是开发工具,还是运行层级?
我现在讨论的是代码语言,还是系统模块?
我现在讨论的是编译时看到的东西,还是设备运行时真正执行的东西?
只要这三个问题问清楚,NDK、SDK、APP、Framework、Native 就不会再混成一团。
一、先建立坐标系:这些词不在同一条线上
很多时候不是定义有多难,而是我们把几个不同视角的词放在了一条线上。
先按四个视角拆开看:
java
工具包维度:
SDK、NDK
交付物维度:
APP、APK、AAB、library、.so
系统分层维度:
App、Framework、System Service、Native Service、HAL、Kernel
语言和运行实现维度:
Java/Kotlin、C/C++、ART、JNI、native method、native crash
同一个对象可以同时落在多个维度里。
比如一个普通 Android App:
从交付物看:
它是 APK/AAB。
从系统分层看:
它运行在 App 层。
从开发工具看:
它通常使用 Android SDK 编译、打包和调试。
从语言实现看:
它可以主要由 Kotlin/Java 写成,也可以包含 C/C++ 编译出来的 .so。
再比如一个使用 NDK 的视频处理 App:
java
它仍然是 App。
它仍然运行在 App 进程和 App 沙箱里。
它仍然会使用 Android SDK 访问 Activity、Camera、MediaCodec 等 API。
它额外使用 NDK 把 C/C++ 编译成 native library。
它的 .so 是 App native code,不自动等于 Android 系统 native service。
所以,别急着用一句"这是 native"解决所有问题,最好先补一句:
java
这是 App 里的 native library?
还是 AOSP 里的 native daemon?
还是 Framework JNI 的 native 实现?
还是 Java 方法声明里的 native 关键字?
还是产品形态里说的 native App?
一个词能不能说清楚,取决于上下文有没有说清楚。
二、SDK 是什么?为什么它不是 Framework?

SDK 的全称是 Software Development Kit,软件开发工具包。
放到 Android 里,Android SDK 可以理解为:Android 提供给应用开发者的一套开发入口。
它通常包含这些东西:
markdown
platforms/android-xx/android.jar:
编译时使用的 Android API 声明。
build-tools:
aapt2、d8、zipalign、apksigner 等构建和打包工具。
platform-tools:
adb、fastboot 等和设备交互的工具。
cmdline-tools:
sdkmanager、avdmanager、lint 等命令行工具。
emulator 和 system images:
用于创建和运行模拟器。
文档、samples、API reference:
用于理解 API 行为和开发方式。
这里最容易误解的是 android.jar。
很多人看到 App 代码里写:
ini
val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
或者:
scss
startActivity(intent);
就会觉得"我在调用 SDK"。这个说法在开发者视角下可以成立,但更准确地说:
markdown
编译时:
你的代码依赖 SDK 里的 API 声明。
运行时:
你的代码调用的是设备系统里真正的 Framework 实现。
android.jar 更像一个编译契约。它告诉编译器:
这些类存在。
这些方法可以调用。
这些参数和返回值是什么。
这些 API 属于当前 compileSdk 能看到的范围。
但它不是设备上真正执行的完整 Framework。
设备运行时,真正提供能力的是系统镜像里的 Framework、ART、system_server、native service、HAL、Kernel 等一整套系统组件。
所以 SDK 和 Framework 的关系可以这样压住:
SDK 是开发者编译和调用 Android 能力时看到的工具包和 API 契约。
Framework 是 Android 系统在设备上提供这些能力的实现和抽象层。
再换一句更直接的话:
SDK 是"你怎么编译、怎么引用、能看到哪些 API"。
Framework 是"设备里谁真正实现这些 API,谁真正处理这些请求"。
因此,SDK 不是 Framework。SDK 只是把 Framework 的一部分能力以稳定 API 的形式暴露给 App 开发者。
三、NDK 是什么?为什么它不是 Android Native 层?

NDK 的全称是 Native Development Kit,原生开发工具包。
Android 官方对 NDK 的核心定位很明确:它是一套工具,让你可以用 C/C++ 实现 App 的一部分代码。
NDK 通常包含这些东西:
markdown
Clang/LLVM toolchain:
用来把 C/C++ 编译成 Android 可运行的机器码。
sysroot、headers、libraries:
提供 Android 支持的 native API 声明和链接入口。
CMake / ndk-build 集成:
帮助 Gradle 构建 native library。
ABI 支持:
arm64-v8a、armeabi-v7a、x86_64 等。
调试和符号工具:
lldb、addr2line、objdump、readelf 等相关能力。
使用 NDK 后,常见结果是生成一个或多个 .so:
bash
app/src/main/jniLibs/arm64-v8a/libxxx.so
app/build/intermediates/merged_native_libs/...
APK/lib/arm64-v8a/libxxx.so
App 运行时通过 JNI 或其他 native 入口加载这些 .so,然后在 App 进程里执行 C/C++ 代码。
关键点来了:NDK 不是 Android 系统的 Native 层本身。
NDK 是工具包。Native 层是运行实现或系统分层。
这两个概念的关系更像这样:
java
NDK:
面向 App 开发者的 native 开发工具包。
App native library:
用 NDK 编译出来、随 App 一起安装的 .so。
Android native layer:
AOSP 中的 C/C++ 系统组件、native library、native service、daemon、HAL 相关实现等。
比如你用 NDK 写了一个图像滤镜库:
rust
Kotlin/Java UI
-> JNI
-> libfilter.so
-> C++ 算法
这叫 App 使用 NDK 写了一部分 native code。
但它不等于你在修改 SurfaceFlinger、AudioFlinger、netd、vold、init、libbinder、libcutils 这些 Android 系统 native 组件。
所以看到"NDK 开发"时,要先问:
这是 App 里的 C/C++ 代码?
还是 AOSP 系统源码里的 C/C++ 模块?
前者通常是应用 native 开发。后者才更接近整机系统开发里说的 native 层开发。
四、APP 是什么?为什么 APP 里可以同时有 SDK 和 NDK?
APP 不是语言概念,也不是工具包概念。
在 Android 里,APP 更接近一个交付和运行单位。
它通常表现为:
markdown
开发阶段:
一个 Gradle module 或多个 module 组成的应用工程。
构建产物:
APK 或 AAB。
安装后:
一个 packageName,对应 UID、权限、数据目录、组件声明等。
运行时:
一个或多个 Linux 进程,通常运行在应用沙箱中。
一个 App 里可以包含很多东西:
markdown
classes.dex:
Kotlin/Java 编译后的字节码。
resources.arsc 和 res/:
资源文件。
AndroidManifest.xml:
组件、权限、特性、provider、service 等声明。
lib/arm64-v8a/*.so:
native library。
assets/:
原始资源。
所以 App 和 SDK/NDK 的关系不是并列关系,而是:
java
App 是最终交付物和运行主体。
SDK 是开发这个 App 时使用的主要 Android 工具包和 API 契约。
NDK 是当这个 App 需要 C/C++ 时额外使用的 native 工具包。
放到常见场景里就是:
markdown
只用 Kotlin/Java 的 App:
使用 SDK,不一定使用 NDK。
包含 C/C++ 的 App:
使用 SDK,也使用 NDK。
系统预装 App:
仍然是 App,但可能使用普通 Android API、System API,甚至访问部分隐藏接口。
平台 Framework 模块:
不是普通 App,通常随系统镜像构建和更新。
一个 App 带了 .so,并不会改变它作为 App 的本质。
它只是说明:
css
这个 App 的一部分逻辑运行在 native code 中。
它仍然受 App UID、SELinux 域、权限模型、进程沙箱、API 限制约束。
这也是排查问题时很重要的一点。比如一个三方 App 出现 native crash:
markdown
现象:
tombstone 里看到 SIGSEGV、libxxx.so。
结论:
这是 native crash。
但不能直接得出:
这是 Android 系统 native 层的问题。
更准确的判断:
先看崩溃进程是谁,崩溃库是谁,库来自 /data/app 还是 /system/lib64、/vendor/lib64。
如果崩在 /data/app/.../lib/arm64/libxxx.so,大概率是 App 自己的 native library。
如果崩在 /system/bin/surfaceflinger、/system/bin/netd、/system/lib64/libbinder.so、/vendor/bin/hw/...,才更可能进入系统 native、HAL 或 vendor 侧分析。
五、Framework 是什么?为什么它比 SDK 更大?
Framework 是 Android 系统向 App 和上层模块提供能力的框架层。
它不是单个 jar,也不是单个进程,更不是 SDK 的另一个名字。
从 App 开发者视角看,Framework 像一组 API:
sql
Activity
Service
ContentProvider
BroadcastReceiver
View
Window
PackageManager
ActivityManager
PowerManager
ConnectivityManager
TelephonyManager
CameraManager
从系统开发者视角看,Framework 是一套横跨多进程、多模块的系统能力抽象:
markdown
frameworks/base/core:
App 进程中也会加载的 Framework Java 类。
frameworks/base/services:
system_server 中大量系统服务的实现。
Binder 接口:
App 进程和 system_server、native service 通信的边界。
System API / hidden API:
给系统 App、厂商、平台内部使用的非公开能力。
JNI bridge:
Framework Java 代码进入 native 实现的桥。
所以 Framework 的核心不是"Java 层"三个字,而是:
它把底层复杂能力抽象成上层可调用的系统能力。
比如你在 App 里调用:
ini
val pm = context.packageManager
val info = pm.getPackageInfo(packageName, 0)
表面上看只是调用一个 Java/Kotlin API,但真实链路可能是:
shell
App 进程
-> Framework API / proxy
-> Binder
-> system_server
-> PackageManagerService
-> settings/packages.xml、权限状态、安装状态等系统数据
-> Binder 返回
-> App 得到结果
这里 SDK 只解决编译时"能不能调用 getPackageInfo"的问题。
Framework 才是设备运行时真正处理 Package 信息、权限、安装状态、跨进程通信和结果返回的系统实现。
这里可以先记住这层关系:
SDK 是 Framework 对 App 开发者公开出来的 API 窗口和工具集合。
Framework 是系统里真正承载这些 API 的实现、服务和抽象层。
六、Native 是什么?为什么它最容易被说乱?
Native 是这里最容易混乱的词,因为它在不同上下文里有不同含义。
常见至少有五种:
java
第一种:语言层面的 native code
指 C/C++ 这类编译成本机机器码运行的代码。
第二种:Java 语法里的 native 方法
指 Java 方法没有 Java 实现,具体实现通过 JNI 映射到 C/C++。
第三种:App 里的 native library
指 App 随包携带的 .so,比如 libfoo.so。
第四种:Android 系统 native 层
指 AOSP 里的 native daemon、native service、C/C++ library,比如 init、logd、netd、SurfaceFlinger、libbinder。
第五种:产品形态里的 native App
指相对 Web App、Hybrid App、跨平台壳而言,更贴近平台原生能力开发的 App。
这五种都可能被简称为 native,但它们不是一回事。
比如:
csharp
private native long nativeInit();
这里的 native 是 Java 方法修饰符,意思是:
java
这个 Java 方法的实现不在 Java 代码里,而在 native 代码里。
它通常通过 JNI 绑定到 C/C++ 函数。
再比如:
bash
/system/bin/surfaceflinger
/system/bin/netd
/system/lib64/libbinder.so
/vendor/bin/hw/android.hardware.camera.provider-service
这里说的 native 更接近 Android 系统 native 层或 vendor native 实现。
再比如:
bash
APK/lib/arm64-v8a/libopencv_java4.so
APK/lib/arm64-v8a/libgame.so
这里说的是 App 携带的 native library。
所以,看到 native 这个词时,必须补一句上下文:
java
native method?
native library?
native crash?
native service?
native layer?
native app?
没有上下文的 native,信息量其实是不够的。
七、放到一条真实调用链里看

抽象概念说完,最好放到一条调用链里。
假设一个 App 打开相机,里面还有一段 C++ 图像处理逻辑:
sql
App UI:
Kotlin/Java 写 Activity、View、权限申请、预览界面。
SDK:
编译时使用 Camera2、Activity、Permission 等 Android API 声明。
Framework:
运行时 App 调用 CameraManager 等 Framework API。
Binder:
Framework 代理把请求跨进程发给系统服务。
System / Native Service:
camera service 等系统组件处理请求。
HAL:
标准接口连接厂商 camera provider 实现。
Kernel / Driver:
驱动和硬件完成真正的数据采集。
NDK:
App 用 NDK 编译 C++ 图像算法,产出 libimage_filter.so。
App native library:
App 通过 JNI 调用 libimage_filter.so 处理图像帧。
整理成一条链:
markdown
开发阶段:
Android SDK 提供 App API、构建工具、adb 等。
Android NDK 提供 C/C++ 编译和链接能力。
安装阶段:
App 被打包成 APK/AAB,里面可能包含 dex、资源、manifest、.so。
运行阶段:
App 进程加载 Framework 类和自己的 native library。
App 通过 Framework API 请求系统能力。
Framework 通过 Binder 进入 system_server 或 native service。
系统服务继续访问 HAL、vendor、kernel、driver。
这条链里,每个词的位置都不一样:
markdown
SDK:
主要站在开发和编译视角。
NDK:
主要站在 C/C++ 构建和 App native library 视角。
APP:
主要站在安装包、进程、权限、沙箱和业务功能视角。
Framework:
主要站在系统能力抽象和运行实现视角。
Native:
需要看上下文,可能是 App .so,也可能是系统服务,也可能是 JNI 方法实现。
这样就不会把"我用了 NDK"误读成"我在改 Android 系统 native 层"。
也不会把"我调用了 SDK API"误读成"SDK 在设备上帮我完成了所有事情"。
八、如何快速判断一个问题属于哪一类?

排查问题时,可以用下面这组问题快速定位概念边界。
1. 这是开发工具问题吗?
如果你遇到的是:
compileSdk 配置
minSdk / targetSdk
Gradle 构建失败
adb 连接失败
Android SDK Platform 没安装
Build Tools 版本问题
签名、打包、aapt2、d8、R8、lint
先看 SDK、Android Studio、Gradle 和构建工具这条线。
如果问题发生在编译、打包、安装、调试工具链阶段,先看 SDK 和构建链。
2. 这是 C/C++ 构建或 ABI 问题吗?
如果你遇到的是:
typescript
CMakeLists.txt
ndkVersion
abiFilters
arm64-v8a / armeabi-v7a
undefined symbol
dlopen failed
JNI 方法找不到
libxxx.so 没被打进 APK
native debug symbols
先看 NDK、native library、ABI 和 JNI 这条线。
java
如果问题发生在 App 自己的 C/C++ 编译、链接、加载、JNI 绑定阶段,先看 NDK 和 App native library。
3. 这是 App 运行身份问题吗?
如果你遇到的是:
objectivec
权限不够
后台限制
前台服务限制
应用数据目录
UID / packageName
AndroidManifest 声明
组件启动失败
targetSdk 行为变化
先按 App 的运行身份来分析。
go
如果问题和 package、UID、权限、组件、manifest、targetSdk 行为有关,先按 App 运行身份分析。
4. 这是 Framework 状态或系统服务问题吗?
如果你遇到的是:
bash
ActivityManagerService
PackageManagerService
WindowManagerService
PowerManagerService
ConnectivityService
system_server
Binder 调用异常
系统 API 行为异常
frameworks/base 修改
先看 Framework、system_server 和 Binder 调用链。
如果问题发生在系统能力抽象、系统服务状态机、跨进程调用链里,先看 Framework 和 system_server。
5. 这是系统 native 或 HAL 问题吗?
如果你遇到的是:
bash
surfaceflinger 崩溃
netd 异常
vold 挂掉
logd、init、servicemanager
/system/lib64/*.so
/vendor/lib64/*.so
HAL service
vendor process
tombstone 指向系统 native 进程
这时再进入 Android native layer、HAL、vendor 或 kernel 边界去查。
bash
如果崩溃进程或核心库来自 /system、/vendor,且属于系统服务、native daemon、HAL service,再进入系统 native 分析。
九、几个最常见的混淆
混淆一:SDK 等于 Framework
不是。SDK 是开发工具包和 API 契约,Framework 是设备端系统能力的实现和抽象层。
App 编译时依赖 SDK 暴露的 API。
App 运行时调用设备里的 Framework 实现。
混淆二:NDK 等于 Native 层
不是。NDK 是 App 开发者写 C/C++ 的工具包,Android Native 层是系统分层里的 C/C++ daemon、service、library、HAL 等。
java
使用 NDK 可以写 App native library。
修改 Android native layer 通常是在 AOSP、vendor、HAL 或系统 native service 里工作。
混淆三:用了 C++ 的 App 就不是 App 了
不是。
App 是否是 App,主要看它是不是以 Android 应用形式安装、运行、授权和管理。
里面用 Kotlin、Java、C++、Rust 或其他语言,不改变它作为 App 的基本身份。
更合适的说法是:
java
这是一个包含 native library 的 App。
混淆四:native 崩溃就是 NDK 崩溃
不一定。
native 崩溃只说明崩在 native 代码路径里。它可能来自:
java
App 自己的 .so
三方 SDK 的 .so
系统 native library
native daemon
HAL service
vendor library
判断入口不是"有没有 SIGSEGV",而是:
bash
崩溃进程是谁?
崩溃线程在做什么?
backtrace 里的 so 来自哪里?
库路径是 /data/app,还是 /system、/vendor?
符号属于 App、三方库、Framework JNI、native service,还是 HAL?
混淆五:Framework 就是 Java,Native 就是 C++
太粗。
Framework 里确实有大量 Java 代码,但 Framework 也会通过 JNI 进入 native,实现中也有 native bridge 和底层服务协作。
Native 里确实有大量 C/C++,但不是所有 C/C++ 都属于系统 native 层。App 自己的 .so 也是 C/C++,但它运行在 App 进程里。
更稳妥的说法是:
Framework 是系统能力抽象层,不只是语言标签。
Native 是实现方式或系统层级标签,必须结合进程、路径、模块一起判断。
十、用一张表压住边界
| 名词 | 主要维度 | 它是什么 | 常见位置 | 最容易误解成 |
|---|---|---|---|---|
| SDK | 工具包 / API 契约 | App 开发、编译、调试、打包所需工具和公开 API | Android SDK 目录、Android Studio、Gradle 配置 | Framework 本身 |
| NDK | 工具包 / C/C++ 构建 | 用 C/C++ 实现 App 部分逻辑的工具链 | ndk/、CMake、.so、JNI |
Android 系统 Native 层 |
| APP | 交付物 / 运行身份 | APK/AAB、package、UID、进程、权限、组件 | /data/app、App 进程、manifest |
某种固定语言实现 |
| Framework | 系统分层 / 能力抽象 | Android API、系统服务、Framework Java、system_server 等 | frameworks/base、system_server、Manager/Service |
SDK |
| Native | 语言 / 实现 / 系统层级 | C/C++ 代码、native library、native service、JNI 实现等 | .so、/system/bin、/vendor/bin、JNI |
NDK 或单纯 C++ |
这张表最重要的不是记住每个格子,而是记住第一列和第二列的关系:
SDK、NDK 是"怎么开发"。
APP 是"交付和运行的是什么"。
Framework、Native 是"系统运行时处在哪一层、由谁实现"。
十一、实际工作里怎么说才不容易误会?
如果你想表达"我在写 Android 应用",可以说:
我在做 App 开发,主要使用 Android SDK 和 Kotlin/Java。
如果你想表达"我在 App 里写 C++",可以说:
java
这个 App 使用 NDK 编译了一部分 native library,通过 JNI 调用。
如果你想表达"我在改系统服务",可以说:
我在改 Framework 层的系统服务,比如 PackageManagerService / ActivityManagerService。
如果你想表达"我在改系统 C++ 服务",可以说:
java
我在改 Android native service,比如 SurfaceFlinger / netd / vold。
如果你想表达"我在看硬件抽象层",可以说:
bash
我在看 HAL service 或 vendor 实现,它处在 Framework/native service 和 kernel driver 之间。
如果你想表达"某个 native 崩溃了",最好补完整:
bash
这是 App 进程里的 native crash,崩在 /data/app 下的 libxxx.so。
或者:
bash
这是系统 native 进程崩溃,进程是 surfaceflinger,backtrace 主要在 /system/lib64 和 vendor 库之间。
这样沟通会比一句"native 有问题"清楚得多。
十二、延伸阅读
- Android NDK - Android Developers:确认 NDK 的官方定位,它是让 App 使用 C/C++ 实现部分代码的工具集。
- Update the IDE and SDK tools - Android Developers:查看 SDK Manager、SDK Tools、Build Tools、Platform Tools、SDK Platform 等组成。
- Architecture overview - AOSP:用 AOSP 官方分层校准 Android app、Android framework、system services、HAL、native daemons and libraries、kernel 的位置。
- HAL overview - AOSP:理解 HAL 为什么是 Framework/native service 与厂商底层实现之间的标准接口边界。
总结:最终答案是什么?
这篇文章的核心问题是:
NDK、SDK、APP、Framework、Native 到底怎么区分?
最后可以收成三层意思。
第一,SDK 和 NDK 是工具包,不是系统层级。
java
SDK 面向 Android App 的普通开发、编译、调试和打包。
NDK 面向 App 中 C/C++ native library 的编译、链接和调试。
第二,APP 是交付和运行单位,不代表固定语言。
css
一个 App 可以只用 Kotlin/Java,也可以包含 C/C++ .so。
用了 NDK 的 App 仍然是 App,只是多了一部分 native code。
第三,Framework 和 Native 是系统运行时的分层和实现语境。
java
Framework 负责把系统能力抽象成上层 API 和系统服务。
Native 需要看上下文,可能是 App .so、JNI 实现、系统 native service、native library、HAL 或 vendor 代码。
所以真正的区分方法不是死记名词,而是每次先问:
java
这是工具包,还是运行层?
这是交付物,还是实现代码?
这是 App 自己的 native,还是 Android 系统 native?
这是编译时看到的 SDK API,还是设备运行时的 Framework 实现?
只要这几个问题问对,NDK、SDK、APP、Framework、Native 的边界就会非常清楚。