一、什么是androidsourcesets
androidsourcesets是Android Studio项目中的一个非常重要的概念。它可以让我们在同一个项目中构建多个版本和变体,每个版本和变体可以有自己的代码、资源和配置文件。简单的说,就是我们可以通过androidsourcesets在一个项目中构建出多个独立的apk。 在一个Android Studio项目中,通常会包含两个androidsourcesets:main和androidTest。其中main是主要的源码集,所有版本和变体共享这个源码集。而androidTest则是测试代码的源码集,只有单元测试和Android Instrumentation测试可以使用它。
二、如何使用androidsourcesets
首先,我们需要在build.gradle
文件中定义androidsourcesets:
android {
...
sourceSets {
free {
manifest.srcFile 'src/free/AndroidManifest.xml'
java.srcDirs = ['src/free/java']
res.srcDirs = ['src/free/res']
}
paid {
manifest.srcFile 'src/paid/AndroidManifest.xml'
java.srcDirs = ['src/paid/java']
res.srcDirs = ['src/paid/res']
}
}
}
上面的代码定义了两个androidsourcesets:free
和paid
。每个androidsourcesets都指定了对应的AndroidManifest.xml
、Java源码和资源文件所在目录。
接下来,我们可以在同一个项目中构建出多个版本和变体。例如,在创建buildType
的时候指定使用的androidsourcesets:
android {
...
buildTypes {
debug {
...
}
release {
...
}
customType {
...
resConfigs "en", "fr"
initWith debug
applicationIdSuffix ".customType"
sourceSets {
free {
manifest.srcFile 'src/customTypeFree/AndroidManifest.xml'
java.srcDirs = ['src/customTypeFree/java']
res.srcDirs = ['src/customTypeFree/res']
}
paid {
manifest.srcFile 'src/customTypePaid/AndroidManifest.xml'
java.srcDirs = ['src/customTypePaid/java']
res.srcDirs = ['src/customTypePaid/res']
}
}
}
}
}
上面的代码创建了一个名为customType
的buildType
。为了使用自定义的androidsourcesets,我们需要在customType
里重新定义它们。注意,在customType
里我们可以定义不同的资源配置(使用resConfigs
)或者应用ID后缀(使用applicationIdSuffix
),以便在构建不同的版本和变体时能够正确的识别它们。
三、androidsourcesets常用场景
1、分渠道打包
在实际开发中,我们经常需要将同一个应用打包成不同的渠道,以便于在市场上进行多渠道推广。使用androidsourcesets,我们可以很方便的实现这一功能。例如,在build.gradle
文件中定义渠道相关的androidsourcesets:
android {
...
productFlavors {
xiaomi {
...
sourceSets {
free {
manifest.srcFile 'src/xiaomiFree/AndroidManifest.xml'
java.srcDirs = ['src/xiaomiFree/java']
res.srcDirs = ['src/xiaomiFree/res']
}
paid {
manifest.srcFile 'src/xiaomiPaid/AndroidManifest.xml'
java.srcDirs = ['src/xiaomiPaid/java']
res.srcDirs = ['src/xiaomiPaid/res']
}
}
}
oppo {
...
sourceSets {
free {
manifest.srcFile 'src/oppoFree/AndroidManifest.xml'
java.srcDirs = ['src/oppoFree/java']
res.srcDirs = ['src/oppoFree/res']
}
paid {
manifest.srcFile 'src/oppoPaid/AndroidManifest.xml'
java.srcDirs = ['src/oppoPaid/java']
res.srcDirs = ['src/oppoPaid/res']
}
}
}
}
}
上面的代码定义了两个productFlavors
:xiaomi
和oppo
。每个flavor都定义了对应的androidsourcesets。当使用不同的flavor构建apk时,系统会根据不同的sourceSets打包出不同的apk。
2、分模块开发
在较大的应用中,为了方便开发和维护,我们可以将应用分成多个模块进行开发。使用androidsourcesets,我们可以在一个项目中构建多个独立的模块和apk。例如,在build.gradle
文件中定义不同的androidsourcesets:
android {
...
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
}
module1 {
manifest.srcFile 'src/module1/AndroidManifest.xml'
java.srcDirs = ['src/module1/java']
res.srcDirs = ['src/module1/res']
}
module2 {
manifest.srcFile 'src/module2/AndroidManifest.xml'
java.srcDirs = ['src/module2/java']
res.srcDirs = ['src/module2/res']
}
}
}
上面的代码定义了三个androidsourcesets:main
、module1
和module2
。每个androidsourcesets都定义了对应的AndroidManifest.xml
、Java源码和资源文件所在目录。接下来,我们可以在同一个项目中构建出多个独立的apk。
3、多语言版本开发
在国际化应用中,为了提供更好的用户体验,我们需要提供多语言版本的应用。使用androidsourcesets,我们可以很方便的实现这一功能。例如,在build.gradle
文件中定义不同语言版本的androidsourcesets:
android {
...
productFlavors {
english {
...
sourceSets {
free {
manifest.srcFile 'src/englishFree/AndroidManifest.xml'
java.srcDirs = ['src/englishFree/java']
res.srcDirs = ['src/englishFree/res']
}
paid {
manifest.srcFile 'src/englishPaid/AndroidManifest.xml'
java.srcDirs = ['src/englishPaid/java']
res.srcDirs = ['src/englishPaid/res']
}
}
}
french {
...
sourceSets {
free {
manifest.srcFile 'src/frenchFree/AndroidManifest.xml'
java.srcDirs = ['src/frenchFree/java']
res.srcDirs = ['src/frenchFree/res']
}
paid {
manifest.srcFile 'src/frenchPaid/AndroidManifest.xml'
java.srcDirs = ['src/frenchPaid/java']
res.srcDirs = ['src/frenchPaid/res']
}
}
}
}
}
上面的代码定义了两个语言版本的productFlavors
:english
和french
。每个flavor都定义了对应的androidsourcesets。使用resConfigs
属性,我们可以指定打包时仅使用特定语言的资源。
四、总结
androidsourcesets是Android Studio项目中非常重要的概念,可以让我们在同一个项目中构建多个版本和变体。androidsourcesets常用于分渠道打包、分模块开发和多语言版本开发等场景,对于大型项目非常实用。