文章同步在:https://juejin.cn/post/7235834434645475384,CSDN的有些排版不太友好。
本篇文章主要分享一些自己平时工作中使用AndroidStudio查看aosp的方法,同时抛砖引玉,希望知道其它便利有效的查看调试方式技巧的大佬们能够不吝赐教,大家互相分享,共同进步。
如果直接用AndroidStudio打开aosp根目录,那么打开任意一个Java类,默认情况可能是这样的:
Java文件的标签页显示图标为:
表示“Java class located out of the source root”,并且其内部的成员变量之类的也没有被语法高亮。经过我们配置后,被识别后的Java文件被效果如下图所示:
Java文件的标签页显示图标为 :
且成员变量也被高亮。
更重要的是,此时代码内部已经建立起了索引,比如可以进行代码补全(这里的代码不仅是补全定义在当前类中的域,也可以补全父类的域,以及其它类的域):
或查看某个域被哪些类调用了:
以及代码跳转等一系列便捷功能。
1 主流方法
1.1 设置步骤
第一种方法应该很多人都知道,我从接触Android开始的很长一段时间用的都是这种方法,该方法需要一套已经编译过的AOSP。
1)、首先确保已经执行过:
soruce build/envsetup.sh
等命令加载编译所需的环境变量。
2)、接着执行:
mmm development/tools/idegen/ -j16
编译成功后,会输出:
我这里编译之前设置了生成目录的环境变量为out_sys,所以生成文件在out_sys。
3)、此时可以执行命令:
./development/tools/idegen/idegen.sh
如果你的生成目录也和我一样在out_sys的话,可能需要新建一个out/host/linux-x86/framework/目录,然后将idegen.sh复制过去:
cp out_sys/host/linux-x86/framework/idegen.jar out/host/linux-x86/framework/
当看到有类似输出:
的时候便可以了,最终会在aosp根目录生成两个文件,android.ipr,android.iml:
4)、通过Android打开这个android.ipr。由于是第一次打开源码会为所有模块建立索引,所以耗时非常久,相当长的时间内AndroidStudio卡的都不能使用,这是我放弃使用这种方式查看aosp的主要原因。实不相瞒,我个人已经很久没用过这种方式了,这次是为了写这篇文章所以我又试了一次这种方法,怎么说呢,熟悉的感觉又回来了…慢的让人发指,有的时候你甚至分不清是到底是真的在建索引还是单纯卡死了。
1.2 优缺点
由于卡的时间太久不想等了,所以后面的步骤就不演示了,其实也没啥内容了,说一下这种查看方法下的可能有用的技巧:
- 将你用不到的代码目录设置为excluded,这个操作在此种方式下似乎用处不大。
- 在android.iml中将你用不到的代码目录,从sourceFolder改为excludeFolder,这个方法很有用,不论是在建立索引的时候,还是在你后续查看aosp的时候,都可以帮你过滤掉很多无关代码。
- 将Project Structure -> Modules -> Dependencies下的jar包啥的都删掉,避免代码跳转的时候跳到其它乱七八糟的地方。
这种查看aosp的方式,优点就是一次性为所有模块建立索引,同时也是缺点,第一次加载因为要建立索引所以巨慢,后续再次打开虽然比第一次要快很多,但也是相对的,我个人觉得花的时间还是比较久。
另外之前说的修改android.iml的方法,的确是一个好方法,但是也不是没有缺点,比如配置这个可能比较麻烦,虽然这个配置操作是一劳永逸的,但是如果你换了另一个项目的代码看,那就又需要重新配置这个项目的android.iml,并且又需要经历一次巨TM久的建索引的熬人环节。我当时的做法是将android.ipr和android.iml进行了复用,比如我在项目A上配置过了这两个文件,那么当我重下了一套项目B的代码,我可以直接将项目A的android.ipr和android.iml复制到项目B中复用这两个文件。好处是的确省下了不少时间精力,缺点是如果两个项目中你想查看的文件的名字或所在目录碰巧不一样的话(比如Android平台升级了),可能比较麻烦,以及可能还有一些我没遇到过的未知问题。
如此种种,让我迫切希望寻找另一种查看aosp的方式。
2 简易方法
2.1 设置步骤
第一种方法的缺点我已经吐槽了很多了,但是还有一点也是不能忽视的,就是你需要一套已经编译过的aosp,很多时候我可能只拉了aosp中某一个库的代码,比如frameworks/base这个库,那么我就不能建立内部索引进行查看了吗。
现在的答案是可以,其实也很简单。不过这里还是拿整套aosp举例,操作是一样的:
1)、比如我现在下载了一套项目代码,接着直接将该项目的根目录在AndroidStudio中打开,初始所有的目录都是这样的:
2)、此时关闭掉右下角正在建立索引的操作:
3)、然后先将所有目录全部设置为Excluded:
目录被设置为Excluded后就像这样:
这一步也可以不做,我这么做只是希望一开始的时候就把无关模块排除掉,方便后续建索引和查看代码。
4)、然后重新再打开AndroidStudio,这个时候你会发现建索引的步骤没了,因为所有目录都被排除掉了。
5)、然后你想要查看哪些代码,就把这些代码所在的java目录或者src目录标记为Sources Root(这一步应该是基于IntelliJ IDEA的配置原理,但是我还没找到具体的理论支持内容),比如我经常看WMS相关的内容,在
frameworks\base\services\core\java\com\android\server\wm\
包中,那么我就可以把
frameworks\base\services\core\java
这个目录设置为Sources Root,就像这样:
目录被设置为Sources Root后,结果为:
此时便可以为这个目录重新建立索引了,比如我在WindowContainer.java这个类中,新建一个test方法,看看this都有哪些方法可以调用:
能看到代码补全的功能。
查看isDescendantOf这个成员方法都在哪些类里被调用了,也可以:
其它的就不过多介绍了,我个人目前使用的就是这种查看aosp的方式。
2.2 跳转到SDK的特殊情况
这里说一点可能会遇到的情况,即代码跳转可能会调转到SDK,而不是aosp,比如我通过Ctrl + 鼠标左键想要跳转到Rect这个类里去,发现跳转到了SDK里,而不是aosp中的Rect.java:
这个时候需要将Project Structure -> Modules -> Dependencies中的SDK依赖:
更换为本地的JDK包:
选择完就像这样:
此时再重新尝试跳转到Rect,就可以了:
如果不可以,可能是因为Rect.java位置为:
frameworks\base\graphics\java\android\graphics\Rect.java
你需要将Rect.java所在目录的的java目录:
frameworks\base\graphics\java
设置为Sources Root: