第二章 开发环境搭建:AOSP源码下载、编译环境配置、模拟器与真机调试准备
好,咱们直接进入正题。做 SurfaceFlinger 调试,第一步就是把环境搭起来。这一步要是没弄好,后面全是坑。我个人习惯把环境搭建分成三个部分:源码下载、编译配置、调试准备。咱们一个一个来。
2.1 AOSP 源码下载:别让网络卡住你
下载 AOSP 源码,说白了就是跟 Google 的服务器打交道。国内网络环境你懂的,直接 repo sync 大概率会卡死。我刚开始做的时候,就吃过这个亏——挂了一晚上,第二天一看,才下了 5%。
我个人推荐用中科大的镜像。配置方式很简单:
# 初始化 repo
repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-13.0.0_r30
# 同步源码
repo sync -j4 -c --no-tags
这里有个小技巧:-j4 表示用 4 个线程并行下载。你机器核多的话可以调大,比如 -j8。但别贪心,网络带宽才是瓶颈。我曾经试过 -j16,结果路由器直接罢工了。
为什么会这样?因为 repo sync 本质上是并发拉取多个 git 仓库。AOSP 有几百个仓库,每个仓库都要建立连接。并发太高,你的路由器可能扛不住。
嗯,这里要注意:第一次下载大概需要 60-80GB 空间。确保你的磁盘够用。我建议至少留 200GB 空闲空间,因为后面编译还会生成大量中间文件。
2.2 编译环境配置:Ubuntu 是首选
编译 AOSP,我强烈推荐用 Ubuntu 20.04 或 22.04 LTS。为什么?因为 Google 官方就是用这个环境测试的。你用其他发行版,可能会遇到各种奇奇怪怪的依赖问题。
我记得有一次,一个同事用 Arch Linux 编译,结果死活过不了。折腾了两天,最后换回 Ubuntu,一次通过。所以,别跟自己过不去。
必要的依赖包安装:
sudo apt-get update
sudo apt-get install -y git-core gnupg flex bison build-essential \
zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \
lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig
这里有个坑:不同 Android 版本对 JDK 版本要求不一样。Android 13 需要 OpenJDK 11。你可以用 update-alternatives 来管理多个 JDK 版本。
2.3 编译 AOSP:第一次编译要耐心
编译 AOSP 其实就三步:设置环境、选择目标、开始编译。但第一次编译,你得做好心理准备——我当年第一次编译,用了整整 4 个小时。
# 1. 设置环境
source build/envsetup.sh
# 2. 选择目标
lunch aosp_x86_64-eng
# 3. 开始编译
make -j8
lunch 后面的参数怎么选?我一般用 aosp_x86_64-eng 来调试 SurfaceFlinger。为什么?因为 eng 版本会包含调试符号和 root 权限,方便我们后面用 dumpsys 和 gdb。
你想想看,如果选了 user 版本,很多调试工具都用不了,那还怎么玩?
编译过程中,你可能会遇到各种错误。最常见的是内存不足。AOSP 编译需要至少 16GB 内存,我建议 32GB。如果你用虚拟机,记得给足内存和 CPU 核心数。
🔑 关键参数说明:
| 参数 | 说明 | 我的建议 |
|---|---|---|
-jN |
并行编译线程数 | CPU 核心数的 1.5-2 倍 |
eng |
工程版本,带调试符号 | 调试首选 |
userdebug |
用户调试版本 | 接近真机环境 |
2.4 模拟器调试:快速验证的好帮手
编译完成后,启动模拟器很简单:
emulator
但这里有个问题:模拟器默认的 SurfaceFlinger 配置和真机不太一样。比如,模拟器通常使用软件渲染,而真机用的是硬件合成器(HWC)。
我在项目中遇到过一个问题:在模拟器上调试好的动画效果,到了真机上就卡顿。后来才发现,是 HWC 的合成策略不一样。所以,模拟器适合做功能验证,性能调优还是得上真机。
嗯,这里要注意:启动模拟器前,确保你的显卡驱动支持 OpenGL。否则模拟器会黑屏或者闪退。
2.5 真机调试准备:刷机与 root
真机调试,我推荐用 Pixel 系列。为什么?因为 Google 官方支持,驱动好找,而且解锁 bootloader 很方便。
刷机步骤:
- 解锁 bootloader:
fastboot flashing unlock - 刷入编译好的镜像:
fastboot flashall -w - 重启:
fastboot reboot
刷完机后,记得开启开发者选项中的「USB 调试」和「Stay awake」。这样你调试时屏幕不会自动熄灭。
我曾经犯过一个低级错误:刷完机忘了开启 USB 调试,结果 adb 连不上。最后只能重新刷机。所以,这些基础设置一定要检查好。
2.6 调试工具链:必备武器库
做 SurfaceFlinger 调试,下面这些工具你得熟悉:
| 工具 | 用途 | 常用命令 |
|---|---|---|
| adb | 设备通信 | adb shell, adb logcat |
| dumpsys | 查看系统服务状态 | dumpsys SurfaceFlinger |
| systrace | 性能追踪 | atrace --async_start |
| gdb | 源码级调试 | gdbclient surfaceflinger |
我个人最常用的是 dumpsys SurfaceFlinger。它能输出当前屏幕的合成状态、图层信息、帧率等关键数据。后面几章我们会详细讲怎么解读这些输出。
dumpsys SurfaceFlinger 的输出重定向到文件,然后对比不同场景下的差异。这样能快速定位问题。
2.7 避坑指南:我踩过的那些坑
最后,分享几个我实际踩过的坑,希望能帮你省点时间:
- 磁盘空间不足: 编译 AOSP 至少需要 150GB 空闲空间。我建议用单独的硬盘或者分区。
- 内存不够: 编译时如果出现
Killed错误,多半是内存不足。增加 swap 空间可以临时缓解。 - Python 版本问题: AOSP 13 需要 Python 3.8+。如果你的系统默认 Python 版本太低,记得用
update-alternatives切换。 - 文件系统大小写敏感: AOSP 源码必须在大小写敏感的文件系统上编译。macOS 默认不区分大小写,需要创建区分大小写的磁盘映像。
嗯,环境搭建这部分就到这里。虽然步骤有点多,但一次配好,后面就能省很多事。下一章,我们会正式开始 SurfaceFlinger 的源码分析。准备好了吗?