Android项目中如何为单个source set添加并合并多个manifest?
Android单Source Set下多Manifest文件合并方案
直接连续调用manifest.srcFile会导致后一个文件覆盖前一个,这是因为Android Gradle插件(AGP)明确规定:
// For each source set, you can specify only one Android manifest.
manifest.srcFile 'other/AndroidManifest.xml'
要实现多个Manifest文件的合并,可采用以下几种可行方案:
方案1:利用多Source Set自动合并
创建额外的Source Set存放其中一个Manifest,让目标Source Set依赖这个额外的Source Set,AGP会自动遵循Manifest合并规则完成合并。
示例代码:
android { sourceSets { // 创建额外的source set存放foo的manifest fooManifest { manifest.srcFile 'foo/AndroidManifest.xml' } main { manifest.srcFile 'bar/AndroidManifest.xml' // 让main source set关联fooManifest的manifest目录 manifest.srcDirs += fooManifest.manifest.srcDirs // 若有资源或代码关联,也需同步添加 resources.srcDirs += fooManifest.resources.srcDirs } } }
方案2:自定义Gradle任务预合并
编写Gradle任务在构建前手动合并两个Manifest文件,生成临时文件后让Source Set指向该文件。这种方式可完全自定义合并规则。
示例代码:
// 定义合并manifest的任务 task mergeManifests { def mergedManifest = file("$buildDir/tmp/merged/AndroidManifest.xml") // 声明输入输出文件,让Gradle能正确处理增量构建 inputs.files('foo/AndroidManifest.xml', 'bar/AndroidManifest.xml') outputs.file(mergedManifest) doLast { // 使用XmlSlurper解析并合并两个manifest def baseManifest = new XmlSlurper().parse('foo/AndroidManifest.xml') def overlayManifest = new XmlSlurper().parse('bar/AndroidManifest.xml') // 示例合并逻辑:将overlay中的application子节点追加到base中 // 实际需根据需求处理权限、属性、组件优先级等规则 baseManifest.application.append(overlayManifest.application.children()) // 将合并后的内容写入临时文件 def writer = new FileWriter(mergedManifest) new XmlNodePrinter(new PrintWriter(writer)).print(baseManifest) } } android { sourceSets { main { // 让main source set指向合并后的临时manifest manifest.srcFile mergeManifests.outputs.files.singleFile } } } // 确保编译前先执行合并任务 preBuild.dependsOn mergeManifests
方案3:构建变体Manifest覆盖
如果你的Manifest属于不同的构建变体(如flavor、build type),可将不同的Manifest放在对应变体的目录下,AGP会自动按优先级合并(build type > flavor > main)。
比如将foo/AndroidManifest.xml放在src/flavorFoo/目录,bar/AndroidManifest.xml放在src/main/目录,构建flavorFooDebug变体时会自动合并两者。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

