AOSP (Android 9.0.0)源码下载
现在学习 Android 不像早些年,会写个 App 就能找到饭碗,如今不看看 Framework 源码有种分分钟掉队的感觉。虽然现在有一些比较优秀的站点提供源码阅读,但是毕竟在浏览器里面阅读,还是会遇到很多限制,最好还是自己下载一份。说道下载问题就来了,AOSP 的仓库被墙了,所以直接不能直接下载,或者说直接下载网速会很慢,还好国内有一些镜像服务可以避免这一问题。
之前用 Ubuntu 直接挂个 SS 就能以 2M/s 速度同步源码,但是最近在 Mac 就死活没得办法了。这里我们使用 清华 的源,不过它给的帮助文档似乎并不能直接照搬。
准备工作
准备一块至少 100G 空闲的磁盘作为下载盘(大一点准没错,强烈建议下载到移动硬盘里)。然后 AOSP 编译环境要求 大小写敏感(Case-Sensitive) ,所以先格式化:
然后在这个磁盘(分区)上执行:
1 | mkdir AOSP && cd AOSP |
我们这次下载的是 Android 9.0.0 的源码,所以目录就命名成这样,你也可以选择你喜欢的名字!
下载 repo 工具
整个 AOSP 还是非常巨大的,所以就会把整个项目拆分成许多的版本管理仓库,这么多仓库需要通过工具来进行管理,也就是这里要下载的 repo 工具。执行命令:
1 | cd AOSP |
因为不太喜欢入侵性太强的配置,就不按照官网的配置来弄了,等会直接通过相对路径来引用 repo
。
这个时候 repo
还是从 Google 的站点进行下载,所以还要简单修改一下。使用文本编辑器打开 repo,然后将开头的 REPO_URL
字段值替换成 https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/
。
初始化 repo
默认情况下,通过 repo 同步的将会是整个 AOSP 源码,即各种版本的源码都有,这里我们通过 -b
来指定 Android 9.0.0 分支。其他可选分支 。
然后执行:
1 | cd android-9.0.0_r1 |
终端可能会输出一两句警告信息,忽略就好了。
开始下载
初始化工作已经完成,可以直接开始下载源码了:
1 | cd android-9.0.0_r1 |
一般来讲,接下来的几小时至一整晚的时间内可以不鸟它了,但是下载可能会因为某些问题而中断,所以还要时不时瞄一眼,所以我们写个重试的脚本 sync.sh
:
1 | !/bin/bash |
$?
中保存的是上一条名命令的执行结果状态,0 表示成功,not 0 表示失败,所以直接简单粗暴地开个死循环,每次执行 ../repo sync
之后判断状态,然后决定是否要重试。不过这并不能完美解决我们的问题,因为有时失败后需要删除一个 *.lock
文件,否则还会在相同的地方失败;并且这个脚本一旦开启只有下载成功才会终止,Ctrl+C
也不能终止,只能杀死进程。
如果网络条件不是很好的话,建议挂晚上下载。
导入 AS
源码下载下来后,因为我们只是想阅读源码,所以不用按照官网的上的指引直接执行 make
,那样会导致编译整个工程,等不起。
执行下列命令:
1 | cd android-9.0.0_r1 |
执行第一条命令会有如下输出:
1 | ============================================ |
这里输出了一些配置信息,然后后面做了一些预处理,这里有个新词 ninja ,这是一个新的构建工具,关于它和 Makefile 的区别,可以看 这里 。
执行第二条命令会输出:
1 | Read excludes: 77ms |
执行完之后,会在工程根目录产生 android.ipr
、android.iml
文件,然后就可以使用 AS 打开 android.ipr
文件来导入工程了。
如果 macOS 出现了下面的错误:
1 | internal error: Could not find a supported mac sdk: ["10.10" "10.11" "10.12" "10.13" "10.14"] |
其实只是编译工具里没有明确支持说明 macOS 版本:
1 | ls /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs |
查看 build/soong/cc/config/x86_darwin_host.go#darwinSupportedSdkVersions 定义发现没有 10.15:
1 | darwinSupportedSdkVersions = []string{ |
在后面加上 10.15 就可以了。
如果并不是想看整个 AOSP 的代码,可以在执行这两条命令之前把自己想要排除的目录或者文件添加到
development/tools/idegen/excluded-paths
中,比如我就把 packages 文件夹忽略了,更多的信息可以看一下development/tools/idegen/README
文件。
编译环境方面,一般来讲新版本 AOSP 和最新的 Mac/Linux 系统版本都不会出现环境问题,但是在出现新系统编译旧 AOSP 代码就极有可能出现一些环境错误,比如需要安装 JDK6。这个时候莫要慌,如果不介意在电脑上装一些环境可以按照错误来配置,介意的话,可以装个 Ubuntu 虚拟机来编译,或者更轻量的 Docker
如果是 4.4 的源码,可以使用我构建好的镜像进行编译:
docker run --rm -v /path/to/aosp/source:/android-4.4 dashmrl/aosp-builder-4.4
AS 阅读体验
AS 首次打开这么一个工程真的非常耗时,主要是在做一些 index 操作,我的 MBP15 花了 20min 才完成,所以没有下定决定看源码之前,就不要打开这个工程了,然后也不要轻易关闭这个工程QAQ…
还有可能会遇到 OOM 的问题,可以看看 这里
工程导入后还会遇上一些其他问题,如果发现 IDE 提示文件行数太大、大小写,可以配置一下 IDE 属性,选择 Help 顶部菜单,然后选择 Edit Custom Properties,然后填入:
1 | # 不够就 100000 |
这时候还有可能会出现点击某个类,但是跳转到类 SDK 代码里,而不是 AOSP 的代码,所以这里在配置一下 SDK。
选择 File->Project Structure,然后选中 Module:
选择对应 Module SDK,这里 Android P 就选 28,然后按照图中删除其余的包,保存。
这时候有一些类或方法还是红的不能跳转,大部分原因是因为有 @hide
注释,不过影响也不大。