该文章介绍的方法过时,推荐看(第二弹)使用Android Studio阅读frameworks源码的正确姿势。
前言
最近想阅读下frameworks源码,就折腾了下,学习怎么用Android Studio阅读frameworks源码,下面是配置信息。
- 机器:mac book pro,m1芯片,16GB。
- AOSP源码的存储位置:读写速度只有几百MB每秒的外接硬盘。
这配置,emm,吕布骑狗。
步骤
编译生成ipr和iml文件
-
进入aosp目录
#/path/to/aosp为aosp目录的绝对路径 cd /path/to/aosp
-
配置编译环境。
source build/envsetup.sh#配置编译环境。 lunch#选择构建目标
执行完lunch后,会有一个列表选择可用的构建目标。
选择完后就输入对应的数字,我选了2(原本这里应该选择适合待刷机的Android手机的选项,但我的需求只是阅读源码,选什么理论上区别不大)。
执行lunch命令时可能会报找不到目录或文件的错误,这时候检查下路径中是否包含空格等特殊符号。
-
编译idegen模块
这个模块的相对路径是:
./development/tools/idegen/
该目录下README.md开头部分解释了这个模块的用途:生成IDE配置的。
IDEGen automatically generates Android IDE configurations for IntelliJ IDEA and Eclipse. Your IDE should be able to compile everything in a reasonable amount of time with no errors.
执行命令。
mmm development/tools/idegen/ #单独编译idegen这个模块
mmm用于编译包含Android.bp或Android.mk文件的一个或多个模块,这在aosp的开发过程非常有用,相比于编译整个aosp,只编译某个模块可以大幅缩短编译时间。
#### build completed successfully (11:46 (mm:ss)) ####看到即说明编译成功
执行该命令的过程中,可能会报以下的错误:
-
LISCENCE文件缺失。
如我报的是。
error: external/kotlinx.coroutines/Android.bp:24:1: module "external_kotlinx.coroutines_license": module source path "external/kotlinx.coroutines/LICENSE" does not exist error: external/kotlinc/Android.bp:24:1: module "external_kotlinc_license": module source path "external/kotlinc/LICENSE" does not exist
解决方法很简单,在对应目录下生成相同名字的文件,如。
touch external/kotlinx.coroutines/LICENSE
-
打开太多文件。
panic: open /Volumes/TOSHIBA/Android_Source_Code/system/hardware/interfaces/suspend/aidl/aidl_api/android.system.suspend.control/1: too many open files
这一般是因为系统限制了一个进程可以打开的文件数。
ulimit -n #查看当前每个进程最多可以打开的文件数。
ulimit -n 8192# 将当前terminal进程最多可以打开的文件数设置为8192
-
-
执行idegen.sh生成ipr和iml文件
development/tools/idegen/idegen.sh
Read excludes: 16ms Traversed tree: 1301831ms #看到即执行成功。
拷贝
将frameworks目录,ipr和iml文件拷贝到同一个目录(和我一样使用读写速度不快的外接硬盘存储aosp源码的朋友需要注意,这里需要拷贝到内置硬盘,否则可能会因为读写速度过慢影响体验)。
精简iml文件
删除android.iml中component与frameworks模块无关的内容,删除后应该是这样的。
...
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/./frameworks/av/media/tests/SampleVideoEncoder/app/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/./frameworks/av/media/tests/SampleVideoEncoder/app/src/main/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/./frameworks/av/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/./frameworks/av/media/tests/benchmark/MediaBenchmarkTest/src/main/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/./frameworks/av/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src" isTestSource="true" />
<!--省略很多与frameworks相关的内容-->
<excludeFolder url="file://$MODULE_DIR$/./external/emma" />
<excludeFolder url="file://$MODULE_DIR$/./external/jdiff" />
<excludeFolder url="file://$MODULE_DIR$/out/eclipse" />
<excludeFolder url="file://$MODULE_DIR$/.repo" />
<excludeFolder url="file://$MODULE_DIR$/external/bluetooth" />
<excludeFolder url="file://$MODULE_DIR$/external/chromium" />
<excludeFolder url="file://$MODULE_DIR$/external/icu4c" />
<excludeFolder url="file://$MODULE_DIR$/external/webkit" />
<excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" />
<excludeFolder url="file://$MODULE_DIR$/out/host" />
<excludeFolder url="file://$MODULE_DIR$/out/target/common/docs" />
<excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates" />
<excludeFolder url="file://$MODULE_DIR$/out/target/product" />
<excludeFolder url="file://$MODULE_DIR$/prebuilt" />
</content>
...
module-library与frameworks无关的也一并删除。
嫌该步骤麻烦的朋友可阅读下面路径的README.md在aosp的根目录下配置excluded-paths文件。
development/tools/idegen/README.md
之后用AS打开ipr文件。
添加依赖和配置module
-
添加依赖
-
配置Android模块
到这里,配置就算完成啦,可以美滋滋阅读frameworks源码了,大多数代码都是支持代码跳转(不支持的大都是aidl文件)。