3、开发环境搭建:SDK、ADB、NDK 归纳总结

3.1 开发工具链的核心角色

做 Android 基准测试和帧率监控,有三样东西你必须搞明白:SDK、ADB、NDK。它们仨就是你的"性能优化三件套"。

我个人习惯先搭好环境再动手写代码。为啥?因为环境问题引发的"翻车"案例我见得太多了。你辛辛苦苦写完的测试脚本,跑不起来,最后发现是 SDK 版本对不上——这种事一次就够你长记性。

这三者分工很明确:

  • SDK 提供编译和打包的基础库,是你的"工具箱"
  • ADB 负责设备和电脑之间的通信,是你的"数据管道"
  • NDK 让你能写 C/C++ 代码做底层性能优化,是你的"性能引擎"

下面这张图帮你理清它们之间的关系:

Android 基准测试开发环境知识体系 开发环境搭建 SDK 工具包 ADB 调试桥 NDK 原生开发 sdkmanager 配置 编译工具链 设备通信调试 帧率数据采集 原生性能分析 JNI 接口交互 三者协同工作:SDK 提供编译环境,ADB 负责数据传输,NDK 支撑底层性能优化 缺任何一个,你的基准测试链路都不完整

一句话记住: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

嗯,差不多就这些了。环境搭好了,后面才能专心做测试。你别看这些配置琐碎,它们直接决定了你后续所有工作的稳定性。一步到位,后面省心。