Android12 源码环境搭建与Framework模块定制开发实战指南
1. 环境准备从零搭建Android12开发环境第一次接触Android源码编译的朋友可能会被官网文档吓到动辄几百GB的硬盘需求、复杂的依赖关系确实让人头疼。但别担心跟着我的步骤走保证你能在Ubuntu系统上顺利搭建起Android12的编译环境。我去年在Pixel 4上完整走通过这个流程实测下来最关键的三个准备是硬盘空间、网络环境和系统版本。先说硬件要求这可能是最大的门槛。官方建议64GB内存但实测16GB也能编译成功只是速度会慢不少。我用的是一台32GB内存的工作站完整编译一次大约需要4小时。硬盘方面建议准备至少400GB的SSD空间机械硬盘的编译速度会让你怀疑人生。如果本地机器配置不够可以考虑云服务国内不少云厂商都提供高配Linux实例。软件环境我推荐Ubuntu 20.04 LTS这是经过官方验证最稳定的版本。安装系统后需要先配置基础开发工具sudo apt update sudo apt 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 python3这里有个小技巧如果你在安装依赖时遇到包找不到的情况很可能是软件源的问题。建议换成国内镜像源比如清华或阿里的源速度会快很多。我遇到过最坑的问题是libncurses5-dev包冲突解决方法是用aptitude而不是apt来安装sudo apt install aptitude sudo aptitude install libncurses5-dev2. 源码下载与镜像配置国内下载AOSP源码最大的障碍就是网络连接问题。官方源在国内访问非常不稳定经常断连。经过多次尝试我发现清华和中科大的镜像站是最稳定的选择。下面分享我的完整下载流程包含几个实用技巧。首先配置Repo工具这是Google专门为管理AOSP这种超大型项目开发的版本控制工具mkdir ~/bin PATH~/bin:$PATH curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo chmod ax ~/bin/repo初始化仓库时关键是要指定国内镜像源。我推荐使用中科大的镜像同步频率高且速度稳定mkdir aosp_android12 cd aosp_android12 repo init -u https://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-12.1.0_r11这里有个容易踩的坑repo工具本身也会检查更新默认连的是Google服务器。需要修改~/bin/repo文件把REPO_URL改为国内镜像vim ~/bin/repo # 将REPO_URL改为 REPO_URL https://gerrit-googlesource.proxy.ustclug.org/git-repo开始同步代码时建议使用-j4参数4个线程太高的并发可能导致服务器拒绝连接repo sync -j4这个下载过程非常漫长我花了近12小时才完成。如果中途断连可以反复执行repo sync命令继续下载。有个实用技巧是写个自动重试的脚本#!/bin/bash while [ $? -ne 0 ]; do repo sync -j4 done3. 驱动下载与真机适配源码下载完成后如果想在真机比如Pixel系列上运行还需要下载厂商提供的闭源驱动。这部分官方文档讲得比较模糊我结合自己的踩坑经验详细说明。首先确定你的设备代号和对应的Build ID。以Pixel 4为例设备代号是flame我们下载的源码分支是android-12.1.0_r11对应的Build ID可以在官网查到。然后到Google开发者网站下载对应的驱动包。驱动下载页面有两个文件需要下载设备驱动Google Devices Driver芯片组驱动QCOM Driver下载完成后把这两个zip文件放到源码根目录解压后会得到两个shell脚本。执行时需要先同意许可协议./extract-google_devices-flame.sh ./extract-qcom-flame.sh执行时会提示你阅读许可协议按空格翻页最后输入I ACCEPT确认。驱动文件会被提取到vendor/目录下。这里容易出错的地方是必须确保驱动版本与源码版本完全匹配否则刷机后会出现各种奇怪问题。4. 编译配置与优化技巧环境准备好后就可以开始编译了。Android的编译系统经过多次迭代现在主要使用Soong和Kati两套系统。下面分享我的编译配置和几个提速技巧。首先初始化编译环境source build/envsetup.sh然后选择编译目标。这里要注意区分三种版本类型user正式发布版权限限制最多userdebug调试版保留root权限eng工程版包含所有调试工具我建议选择userdebug版lunch aosp_flame-userdebug开始编译前强烈建议调整ccache配置。ccache可以缓存编译中间结果大幅提升后续编译速度export USE_CCACHE1 export CCACHE_EXEC/usr/bin/ccache ccache -M 50G正式编译使用make命令-j参数根据你的CPU核心数设置。我的机器是16核所以用make -j16第一次完整编译通常需要3-6小时。如果编译中途出错最常见的解决方法是检查是否所有依赖都安装正确尝试make clean后重新编译减少-j参数的值降低并发数编译成功后输出文件会放在out/target/product/flame/目录下。最重要的几个文件是system.img系统镜像boot.img内核镜像vendor.img驱动镜像5. 刷机与调试技巧编译产出需要刷入设备才能验证。Pixel系列的刷机流程比较特殊我总结了一套安全可靠的步骤。首先解锁bootloader注意这会清空手机数据adb reboot bootloader fastboot flashing unlock然后开始刷机fastboot flashall -w这个-w参数表示要清空用户数据。刷机完成后重启设备fastboot reboot刷机后首次启动会很慢可能要10-15分钟。如果卡在开机动画超过20分钟可能是驱动不匹配或编译有问题。为了方便后续调试建议关闭dm-verity校验adb root adb disable-verity adb reboot这样之后就可以remount系统分区进行修改了adb remount6. Framework模块定制开发日常开发中最常修改的就是Framework层完整编译一次太耗时。Android提供了模块化编译机制可以只编译特定模块。下面以最常修改的framework.jar和services.jar为例。修改framework代码后使用以下命令编译make framework-minus-apex编译完成后替换到设备上adb push out/target/product/flame/system/framework/framework.jar /system/framework/ adb shell rm -rf /system/framework/oat /system/framework/arm /system/framework/arm64 adb shell stop adb shell startservices模块的编译稍有不同mmm frameworks/base/services adb push out/target/product/flame/system/framework/services.jar /system/framework/ adb shell stop adb shell start这里有几个实用技巧修改代码前先执行mm命令编译当前模块验证语法错误使用adb logcat | grep AndroidRuntime快速定位崩溃问题修改系统API时要同时更新API文档make update-api7. 常见问题排查在实际操作中我遇到过各种奇怪的问题。这里分享几个典型问题的解决方法问题1repo sync卡住不动解决方法修改~/.repo/manifests.git/config将url改为国内镜像源问题2编译时报内存不足解决方法减少make的-j参数值或者创建swap分区sudo fallocate -l 16G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile问题3刷机后无法启动解决方法检查驱动版本是否匹配尝试刷回官方镜像再重新刷机问题4单编模块后系统不稳定解决方法确保同时更新了所有依赖模块特别是framework-res.apk8. 开发环境优化建议长期做AOSP开发的话有几个环境优化非常值得做IDE配置Android Studio可以导入AOSP源码但需要先生成IDE工程文件source build/envsetup.sh lunch aosp_flame-userdebug make idegen development/tools/idegen/idegen.sh代码搜索配置OpenGrok或者使用Google的Android Code Search增量编译善用mm/mmm命令只编译当前模块自动化脚本编写脚本自动完成常用操作序列备份策略对.repo目录做定期备份避免重新下载这套环境我已经稳定使用了一年多处理过各种定制需求从修改系统API到添加新硬件支持都验证过。最大的体会是一定要做好版本管理每次修改前创建分支详细记录变更内容。Android系统庞大复杂没有详细的开发日志很容易迷失在代码海洋中。