项目开发中,AS(Android Studio)经常会用到通过关键字在项目空间下搜索对应结果。最经常用到的 Find in Path 。例如打开 Find in Path 后,可以选中 Scope tab,选择 All Places 范围去搜索对应的关键字,下方会自动显示对应的搜索结果。
Find in Path 搜索时,可选的tab有 In Project 、 Module 、 Directory 和 Scope 。同时 Scope 下又细分了很多选项,即对应的选择条件,例如 All Places 、 Project Files 、 Project Source Files 等等。但是无论是哪种tab,以及 Scope tab下的哪种方式,有一点我们必须意识到的是,默认情况下是不包含 非项目文件 的。也就是说,对当前项目目录而言,通过 Find in Path 搜索时,哪怕选的是 Scope 下的 All Places ,搜索的结果在一定意义上而言,都不是完整的。仅仅只是列出了项目文件中对应的匹配结果。
纳尼 ? .... 是的。 复制代码
这里首先牵涉到一个名词, 非项目文件 ,即 non-project files 。那到底哪些是 非项目文件 , 非项目文件 又是如何指定的呢?
我们先来直接感受下:
在上图选中 Scope tab的情况下,如果我们点击其右边的 ... ,会进入到一个 Scopes 的自定义界面,在这个界面中,我们可以新增、编辑或删除自定义的 Scope ,其实说白了,就是可以自定义搜索的范围,这个范围,是依据合乎 Scope Pattern 的模式去对应匹配范围,然后就可以针对此范围进行关键字搜索。
例如,如果我想针对Buil目录范围去搜索,可以如下操作:
点击 + >> Local >> 命名Build ,此时可以看到如下界面。
non-project files 这一称谓。并且,即使是我们自定义的
Scope ,无论怎样设置
Pattern ,也将不会包括
非项目文件
。
Scope Pattern 官方文档说明如下:
最简单的,我们填入一个针对项目全局目录下的 Pattern ,可以看到图示结果。
此时,点击 OK ,表明自定义的 Scope 范围创建成功。
我们重新看下搜索结果。
是的,此时依然是不包含 非项目文件 的。
AS中每个模块,在构建项目之前,都有一个 sync 的过程。这其中,包括对每一个模块的配置声明,模块的配置声明,是有 sync 过程中的 Gradle Task 产生,会形成一个 .iml 的文件。每个模块下的 .iml 文件中,都包括了模块名,模块路径,依赖库信息,语言及版本,模块目录等信息。其中,模块目录中就包括了 sourceFolder 和 excludeFolder 声明。
如:
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/kapt/devDebug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/dev/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/dev/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/dev/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/dev/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/kaptKotlin/devDebug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/dev/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/dev/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/devDebug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/kapt/devDebugAndroidTest" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/dev/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/dev/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/dev/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/dev/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/dev/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/dev/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDevDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/kapt/devDebugUnitTest" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/dev/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDevDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/dev/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDev/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDev/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
复制代码
对啦,最后一行的 excludeFolder 就是本文的主角了。在 <content>...</content> 中的, excludeFolder 声明中的,且不存在于 sourceFolder 等声明中目录,就是完整意义上的 非项目文件 。
例如,我们将最后一行 excludeFolder 声明直接删除,再次重新在 Find in Path 搜索对应的关键字,得到的结果如下:
发现了没,我们的搜索结果变多了,多出的结果真是的位置是在 build/intermediates/merged_manifests/... 目录下。
对比上述的 <content>...</content> 中的声明,显然, build/intermediates 是被 excludeFolder 指定后当作了 非项目文件 处理的。因此,一开始是没有显示的。
实际项目开发中,通过 Find in Path 方式进行关键字搜索时,本意往往是希望查得指定条件下的所有搜索结果,并且,一般情况下,我们甚至并不知道还有个 非项目文件 这个概念存在的。尤其在需要针对项目构建过程中的 中间产物 也进行搜索,以此寻得可能的蛛丝马迹,这在特定的需求场景下是非常有意义的。通过上述分析也知道了, Find in Path 这种搜索方式是不起作用的,即使是自定义的 Scope 也是不行的。
当然,这里需要作出两点澄清:
1,在 Find in Path 搜索时,选择 Directory tab时,如果在已知的既定的 非项目文件 目录下搜索,是可以搜索到对应的结果的,因为此时,相当于已经强行指定了 非项目文件 的目录中去搜索了。但是,如果在 非项目文件 目录的父目录,且此父目录为项目文件目录,此时,搜索都是失效的。
可以直观感受下下列对比。
2,在 <content>...</content> 中人为去掉 excludeFolder 或修改对应的配置,只是临时性的短期有效的行为,因为正如前文所说, .iml 文件是 sync 过程中,由 Gradle Task 生成的,例如,当我们修改了 build.gradle 文件等导致需要重新 sync 时, .iml 文件就会被重新生成,被重新复原。况且,及时真的有办法强制改了此文件,我们也要面对项目构建时可能会出现的其他莫名问题,很肯能得不偿失。
那么,在面对需要针对项目目录进行全局关键字搜索时,有无其他更好的方案呢?
目前来看,在AS本身,我是没有发现的。最终直接 grep 大法。
grep -rnl "android.permission.READ_CALL_LOG" . 复制代码
当前目录下,结果都依依列出了。
➜ MyCorn git:(dev) grep -rnl "android.permission.READ_CALL_LOG" . ./MyCorn/build/intermediates/merged_manifests/devDebug/processDevDebugManifest/merged/AndroidManifest.xml ./MyCorn/build/intermediates/transforms/dex/dev/debug/0/classes6.dex ./MyCorn/build/intermediates/transforms/dex/dev/debug/0/classes7.dex ./MyCorn/build/intermediates/tinker_intermediates/AndroidManifest.xml ./MyCorn/build/outputs/logs/manifest-merger-dev-debug-report.txt ./MyCorn/src/main/AndroidManifest.xml ./base/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/mycorn/vendor/js/BaseJsProvider.class ./base/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/mycorn/vendor/js/JsSdkProviderImpl.class ./base/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/mycorn/vendor/js/helper/ContactCallLogHelper$6.class ./.idea/workspace.xml 复制代码