一、源集
1、定义:Android Studio 按逻辑关系将每个模块的源代码和资源进行分组,这个分组叫做源集。
2、main Module 源集包括其所有构建变体共用的代码和资源。这句话很关键,意思是,所有的其他构建变体,src/main是其共同拥有的。在说明BuildType时,我们会通过案例代码进行介绍。
3、其他源集目录为可选项,在您配置新的构建变体时,Android Studio 不会自动为您创建这些目录,用户可以通过File > New 菜单选项新建文件或目录,进行特定源集进行创建。
源集按照构建类别(buildType)、产品倾向(productFlavor)等,分为以下几个类型:
源集 | 备注 |
---|---|
src/main/ | 此源集包括所有构建变体共用的代码和资源。 |
src/<buildType>/ | 创建此源集可加入特定构建类型专用的代码和资源。 |
src/<productFlavor>/ | 创建此源集可加入特定产品风味专用的代码和资源。 |
src/<productFlavorBuildType>/ | 创建此源集可加入特定构建变体专用的代码和资源。 |
例如,要生成应用的“完整调试”版本,构建系统需要合并来自以下源集的代码、设置和资源:
src/fullDebug/(构建变体源集)
src/debug/(构建类型源集)
src/full/(产品风味源集)
src/main/(主源集)
4、源集的Overlay机制。如果不同源集包含同一文件的不同版本,Gradle 将按以下优先顺序决定使用哪一个文件(左侧源集替换右侧源集的文件和设置):
构建变体 > 构建类型[BuildType] > 产品风味[ProductFlavor] > 主源集[main] > 库依赖项
在合并多个清单时,Gradle 会使用专用于试图构建的资源进行编译,这些文件包括:构建变体的文件,其他应用版本共用的 Activity、应用逻辑和资源,从而达到不同的构建,编译不同的资源的目的。
二、源集的创建
Gradle 会按照与 main/ 源集类似的特定组织形式来管理源集文件和目录。例如,Gradle 要求您的“调试”构建类型所特定的 Java 类文件位于 src/debug/java/ 目录中。
以debug为例,源集构建会有如下几种方式:
方式一:
1、打开 Project 窗格并从窗格顶端的下拉菜单中选择 Project 视图。
2、导航至 MyProject/app/src/。
3、右键点击 src 目录并选择 New > Folder > Java Folder。
4、从 Target Source Set 旁边的下拉菜单中,选择 debug。
5、点击 Finish。
方式二:
1、在相同的 Project 窗格中,右键点击 src 目录并选择 New > XML > Values XML File。
2、为 XML 文件输入名称或保留默认名称。
3、从 Target Source Set 旁边的下拉菜单中,选择 debug。
4、点击 Finish。
以上两种方式,都可以创建源集,源集成功创建后,工程展示如下:
三、源集的重定向
可以通过sourceSets {}来设定Gradle module对应的源集路径。
Android SourceSet表示Java,aidl和RenderScript源以及Android和非Android(Java风格)资源的逻辑组。
3.1、属性
属性 | 描述 |
---|---|
aidl | Android AIDL源目录为此源设置。 |
assets | 该资源集的Android Assets目录。 |
compileConfigurationName | 该源集合的编译配置的名称。 |
java | Java源代码由Java编译器编译到类输出目录中。 |
jni | 这个源码集的Android JNI源目录。 |
jniLibs | 这个源码集的Android JNI libs目录。 |
manifest | 该源代码集的Android Manifest文件。 |
name | 这个源集的名称。 |
packageConfigurationName | 此源集合的运行时配置的名称。 |
providedConfigurationName | 此源集合的仅编译配置的名称。 |
renderscript | 该源码集的Android RenderScript源目录。 |
res | 该资源集的Android资源目录。 |
resources | 要复制到javaResources输出目录的Java资源。 |
3.2、方法
方法 | 描述 |
---|---|
setRoot(path) | 将源集的根设置为给定的路径。源集合的所有条目都位于此根目录下。 |
更多属性以及方法详情,请参与官方文档
案例配置: 配置app/other/目录中的源映射到 main源集的某些组件,并更改 androidTest 源集的根目录。
android {
...
sourceSets {
// main源集(source set)的闭包配置。
main {
// 变更Java 的源文件夹,默认的文件夹 = 'src/main/java'.
java.srcDirs = ['other/java']
//如果像以下方式一样,列出来多个文件夹,那么Gradle使用所有的这些文件夹来加载资源,
//并赋予这些文件夹相同的优先级。如果不同的文件夹中定义了相同的资源,那么会产生资源合并错误。
//默认的资源文件夹是 'src/main/res'.
res.srcDirs = ['other/res1', 'other/res2']
//避免多个文件夹出现“父子”依赖关系。例如:如下情况要避免:
//res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
//应该只指定:'other/res1'或者指定'other/res1/layouts' and 'other/res1/strings'
//每个源集只能有一个AndroidManifest.xml清单文件,
//默认情况下,main源集的清单文件在src/main/ 目录中。
manifest.srcFile 'other/AndroidManifest.xml'
...
}
// 创建额外闭包块区配置其他源集
androidTest {
// 如果所有的源集文件都在一个单独的目录中,可以使用setRoot来进行配置。
// 这样子,Gradle就只会加载该区域。例如:如下配置,Gradle只会从src/tests/java/
// 来获取源集文件。
setRoot 'src/tests'
...
}
}
}
...
四、源集的使用
在使用源集进行编译的时候,要特别注意资源合并的优先级的问题。上面也提到了,优先级如下:
构建变体 > 构建类型[BuildType] > 产品风味[ProductFlavor] > 主源集[main] > 库依赖项
详细说明如下:
-
Java文件。如果找到两个或两个以上定义相同Java 类名的源集目录,那么Gradle 就会引发一个构建错误。
例如,在构建调试 APK 时,同时定义 src/debug/Utility.java 和 src/main/Utility.java,会发生编译错误。 这是因为Gradle 在构建中检查这两个目录并引发了“duplicate class”错误。 - 清单合并为单个清单。在合并清单时,将按照上述列表中的顺序指定优先级。也就是说,某个构建类型的清单设置会替换某个产品风味的清单设置,依此类推。
- value资源。values/ 目录中的文件也会合并在一起。如果两个文件同名,例如存在两个 strings.xml 文件,将按照上述列表中的相同顺序指定优先级。也就是说,某个源集文件中定义的值将会替换产品风味中同一文件中定义的值,依此类推。
- res/ 和 asset/ 目录中的资源将打包到一起。如果两个或两个以上的源- 集中定义有同名资源,将按照上述列表中的相同顺序指定优先级。
- 最后,在构建 APK 时,Gradle 会为随库模块依赖项包含的资源和清单分配最低的优先级。
写作不易,耗费心力,如果上面的内容对你有帮助,请随意打赏,让我们坚持下去~