使用动态特性与构建变体时的Manifest合并错误排查
看起来你遇到的Manifest合并报错,核心原因是变体Manifest里的属性替换配置不完整,或者命名空间、标签结构没对齐。下面给你两种可行的解决方案,其中第二种用Gradle占位符的方式更省心,推荐优先尝试:
方法一:修复Manifest合并配置
先把Manifest合并的坑填上,确保每个步骤都符合Android的合并规则:
统一命名空间
不管是main目录还是变体目录下的AndroidManifest.xml,都要在根<manifest>标签里引入必要的命名空间:<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools">main目录的默认配置
在主Manifest里设置默认的按需加载规则,同时写全<dist:module>的完整结构:<dist:module dist:onDemand="true" dist:instant="false" dist:title="@string/title_your_module"> <dist:delivery> <dist:on-demand /> <!-- 对应按需加载的交付类型 --> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module>变体目录的预装配置
在需要预装的变体(比如preInstallflavor或releasebuildType)的Manifest里,重新完整声明<dist:module>标签,同时指定替换属性和新值:<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <dist:module dist:onDemand="false" dist:instant="false" dist:title="@string/title_your_module" tools:replace="dist:onDemand"> <dist:delivery> <dist:install-time /> <!-- 对应预装的交付类型 --> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module> </manifest>这里要注意:必须明确写出
dist:onDemand="false",并且同步修改<dist:delivery>里的标签,否则即使属性替换成功,交付逻辑也会和预期不符。
方法二:用Gradle Manifest占位符(更推荐)
这种方式完全绕开Manifest合并冲突,直接通过Gradle动态注入属性值,维护起来更简单:
在模块build.gradle中配置占位符
根据你的构建变体(productFlavors或buildTypes),给不同变体设置对应的占位值:android { ... // 假如是productFlavors的场景 productFlavors { preInstall { manifestPlaceholders = [ onDemandValue: "false", deliveryType: "install-time" ] } onDemand { manifestPlaceholders = [ onDemandValue: "true", deliveryType: "on-demand" ] } } // 假如是buildTypes的场景 buildTypes { release { manifestPlaceholders = [onDemandValue: "false", deliveryType: "install-time"] } debug { manifestPlaceholders = [onDemandValue: "true", deliveryType: "on-demand"] } } }在main的Manifest中引用占位符
把需要动态变化的属性用占位符替换:<dist:module dist:onDemand="${onDemandValue}" dist:instant="false" dist:title="@string/title_your_module"> <dist:delivery> <dist:${deliveryType} /> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module>这样Gradle会在构建时自动根据当前变体替换对应的值,完全不需要处理Manifest合并的问题。
为什么你之前的配置失败?
你遇到的报错no new value specified,大概率是因为变体Manifest里的<dist:module>标签没有明确写出dist:onDemand="false",或者命名空间缺失导致合并工具无法识别新的属性值。另外,没有同步修改<dist:delivery>的内容也可能引发潜在的逻辑冲突,建议按照上面的完整结构来配置。
内容的提问来源于stack exchange,提问作者Lukas Lechner

