Android Studio阅读frameworks源码的正确姿势

2,569 阅读3分钟

该文章介绍的方法过时,推荐看(第二弹)使用Android Studio阅读frameworks源码的正确姿势

前言

最近想阅读下frameworks源码,就折腾了下,学习怎么用Android Studio阅读frameworks源码,下面是配置信息。

  • 机器:mac book pro,m1芯片,16GB。
  • AOSP源码的存储位置:读写速度只有几百MB每秒的外接硬盘。

这配置,emm,吕布骑狗。

步骤

编译生成ipr和iml文件

  1. 进入aosp目录

    #/path/to/aosp为aosp目录的绝对路径
    cd /path/to/aosp
    
  2. 配置编译环境。

    source build/envsetup.sh#配置编译环境。
    lunch#选择构建目标
    

    执行完lunch后,会有一个列表选择可用的构建目标。

    image.png 选择完后就输入对应的数字,我选了2(原本这里应该选择适合待刷机的Android手机的选项,但我的需求只是阅读源码,选什么理论上区别不大)。

    执行lunch命令时可能会报找不到目录或文件的错误,这时候检查下路径中是否包含空格等特殊符号。

  3. 编译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
      
  4. 执行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

  • 添加依赖

    image.png

    image.png

    image.png

  • 配置Android模块 image.png

到这里,配置就算完成啦,可以美滋滋阅读frameworks源码了,大多数代码都是支持代码跳转(不支持的大都是aidl文件)。 image.png

参考资料

1.Android Studio 导入frameworks源码