3、开发环境搭建:SDK、ADB、NDK 归纳总结
3.1 开发工具链的核心角色
做 Android 基准测试和帧率监控,有三样东西你必须搞明白:SDK、ADB、NDK。它们仨就是你的"性能优化三件套"。
我个人习惯先搭好环境再动手写代码。为啥?因为环境问题引发的"翻车"案例我见得太多了。你辛辛苦苦写完的测试脚本,跑不起来,最后发现是 SDK 版本对不上——这种事一次就够你长记性。
这三者分工很明确:
- SDK 提供编译和打包的基础库,是你的"工具箱"
- ADB 负责设备和电脑之间的通信,是你的"数据管道"
- NDK 让你能写 C/C++ 代码做底层性能优化,是你的"性能引擎"
下面这张图帮你理清它们之间的关系:
一句话记住:SDK 是"编译器",ADB 是"数据线",NDK 是"加速器"。三者在手,性能测试不愁。
3.2 SDK——基准测试的"地基"
SDK 是 Android 开发的起点。没有它,你连一个 APK 都编译不出来。基准测试也不例外。
我遇到过不少新手,一上来就装最新版 SDK,结果跟 Gradle 插件对不上,编译报错一堆。嗯,这里要注意:SDK 版本不是越新越好,关键要跟你的 AGP(Android Gradle Plugin)匹配。
核心配置项:
- ANDROID_HOME 环境变量——必须配,否则很多工具找不到 SDK 路径
- platforms 目录——包含各版本 Android 框架的 .jar 文件
- build-tools 目录——包含 aapt、dx、zipalign 等编译工具
用 sdkmanager 命令行管理包,我建议你养成这个习惯:
# 列出所有可安装的包
sdkmanager --list
# 安装指定平台(比如 Android 13)
sdkmanager "platforms;android-33"
# 安装构建工具
sdkmanager "build-tools;33.0.0"
# 更新所有已安装的包
sdkmanager --update
实用技巧:用 sdkmanager --list | grep "platforms" 可以快速筛选出所有可用的平台版本。我个人习惯把输出重定向到一个文本文件里,方便对比。
之前有个项目,我需要针对 Android 12 做帧率测试。结果发现 SDK 里只装了 Android 13 的平台包,编译出来的 APK 在真机上各种诡异闪退。查了半天,就是 SDK 平台版本不匹配。从那以后,我每次搭环境都会用 sdkmanager --list 确认一下。
3.3 ADB——帧率监控的"眼睛"
ADB(Android Debug Bridge)是你连接设备和电脑的桥梁。说白了,它就是你的"数据管道"。所有帧率数据、日志、性能指标,都得通过它来传输。
帧率监控最常用的 ADB 命令:
# 检查设备连接状态
adb devices
# 获取指定应用的帧率统计数据
adb shell dumpsys gfxinfo <package_name> framestats
# 实时查看帧率(需要 Android 6.0 以上)
adb shell dumpsys gfxinfo <package_name>
我印象最深的一次,是帮一个电商 App 做性能优化。用户反馈首页滑动掉帧严重,我们用 ADB 抓了 dumpsys gfxinfo 的数据,发现帧绘制时间平均达到了 28ms,远超 16ms 的阈值。原因是一个图片库在 UI 线程做了大量解码操作。没有 ADB,这类问题你根本抓不到。
注意:用 adb shell dumpsys gfxinfo 采集帧率数据时,目标应用必须开启"GPU 渲染模式分析"。可以在开发者选项中开启,也可以通过命令 adb shell setprop debug.hwui.profile true 开启。
ADB 还有一个容易被忽略的用法——无线调试。当你的设备不方便插线时(比如做长时间的温度测试),用无线 ADB 非常方便:
# 先通过 USB 连接,然后开启无线端口
adb tcpip 5555
# 拔掉 USB,通过 IP 连接
adb connect 192.168.1.101:5555
3.4 NDK——原生性能的"手术刀"
NDK 允许你用 C/C++ 编写代码,然后通过 JNI 调用到 Java/Kotlin 层。在基准测试场景里,它有两个核心用处:
- 编写高性能的计算密集型测试用例(比如图像处理、物理模拟)
- 直接操作底层内存和文件系统,避免 GC 干扰
我建议大家在配置 NDK 时,一定要注意版本对齐。Gradle、CMake、NDK 三者之间是有兼容性矩阵的。我曾经因为 NDK 版本跟 CMake 不匹配,导致编译时链接器报了一堆看不懂的符号缺失错误。查了三天,最后发现只是版本问题。
配置示例:
// build.gradle (app 级别)
android {
ndkVersion "25.1.8937393"
defaultConfig {
ndk {
// 指定目标 CPU 架构
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
cppFlags "-std=c++17"
arguments "-DANDROID_STL=c++_shared"
}
}
}
用 NDK 做基准测试的好处是你可以精确控制内存分配和线程调度。举个例子,你想测试某种排序算法在移动设备上的真实性能,用 Java 写会受到 GC 和 JIT 的影响,数据不纯粹。用 C++ 写,通过 JNI 调用,结果就干净多了。
一个小建议:刚开始接触 NDK 做测试时,先从简单的数值计算入手。比如写一个矩阵乘法函数,对比 Java 和 C++ 的执行时间。这能帮你快速验证 NDK 是否配置正确。
3.5 环境验证清单
环境搭完了,怎么确认一切正常?我整理了一份验证清单,每条都对应一个命令。照着跑一遍,有问题早发现。
| 验证项 | 命令 | 预期结果 |
|---|---|---|
| SDK 路径 | echo $ANDROID_HOME |
输出 SDK 所在目录路径 |
| SDK 平台 | ls $ANDROID_HOME/platforms/ |
列出已安装的平台版本 |
| ADB 可用 | adb version |
显示 ADB 版本号和路径 |
| 设备连接 | adb devices |
显示已连接的设备列表 |
| NDK 安装 | ndk-build --version |
显示 NDK 版本号 |
| CMake 可用 | cmake --version |
显示 CMake 版本号 |
建议:把这六条命令保存成一个 shell 脚本,每次换电脑或者重装环境后跑一遍。我每次入职新公司都会这么干,省得手敲。
3.6 避坑指南
搭环境这事,说简单也简单,说坑也多。我踩过不少,挑几个典型的跟你说说。
坑一:ANDROID_HOME 路径里带了空格。比如 "C:\Program Files\Android\SDK"。很多命令行工具在解析路径时会被空格搞疯。我建议你把它放在无空格的路径下,比如 "C:\Android\SDK"。
坑二:多个 NDK 版本冲突。有时候项目 A 需要 NDK r23,项目 B 需要 NDK r25。我建议用 ndkVersion 在 build.gradle 里显式指定,而不是依赖全局路径。
坑三:ADB 连不上设备。90% 的情况是因为 USB 驱动没装,或者开发者选项里的 USB 调试没开。还有 10% 是数据线的问题——换根线试试,真的。
还有一种情况容易忽略:代理设置。在公司内网搭环境时,sdkmanager 下载包可能会因为代理超时而失败。这时候你需要配置 Gradle 的代理参数:
# gradle.properties
systemProp.http.proxyHost=proxy.company.com
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=proxy.company.com
systemProp.https.proxyPort=8080
嗯,差不多就这些了。环境搭好了,后面才能专心做测试。你别看这些配置琐碎,它们直接决定了你后续所有工作的稳定性。一步到位,后面省心。