一、什么是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常用于分渠道打包、分模块开发和多语言版本开发等场景,对于大型项目非常实用。