Android Studio 多个AndroidManifest.xml清单合并规则

合并多个AndroidManifest.xml清单

APK 或 Android App Bundle 文件只能包含一个 AndroidManifest.xml 文件,但 Android Studio 项目可以包含多个清单文件,这些清单文件由主源代码集、build 变体和导入的库提供。因此,在构建应用时,Gradle 构建系统会将所有清单文件合并成一个清单文件打包到应用中。

清单合并工具遵循某些合并启发法和您使用特殊 XML 属性定义的合并偏好设置,来将各个清单文件中的所有 XML 元素组合在一起。
提示:使用 Merged Manifest 视图可预览合并后的清单结果并找出冲突错误。
打开manifest文件,在左下角的位置;
在这里插入图片描述

合并优先级

合并工具会根据每个清单文件的优先级按顺序合并,将所有清单文件组合到一个文件中。例如,如果您有三个清单文件,则会先将优先级最低的清单合并到优先级第二高的清单中,然后再将合并后的清单合并到优先级最高的清单中:
在这里插入图片描述
有三种基本的清单文件可以互相合并,它们的合并优先级如下(按优先级由高到低的顺序):

  1. 构建变体的清单文件

如果变体有多个源代码集,则其清单优先级如下:

  • 构建变体清单(如 src/demoDebug/)
  • 构建类型清单(如 src/debug/)
  • 产品变种清单(如 src/demo/)

如果您使用的是变种维度,则清单优先级与每个维度在 flavorDimensions 属性中的列示顺序(按优先级由高到低的顺序)对应。

  1. 应用模块的主清单文件
  2. 所包含的库中的清单文件

如果您有多个库,则其清单优先级与依赖顺序(库出现在 Gradle dependencies 代码块中的顺序)一致。

例如,先将库清单合并到主清单中,然后再将主清单合并到构建变体清单中。

合并冲突启发法

如果优先级较低的清单中的某个元素与优先级较高的清单中的所有元素都不匹配,则会将该元素添加到合并后的清单中。不过,如果有匹配的元素,则合并工具会尝试将每个元素的所有属性组合到同一元素中。如果该工具发现两个清单包含相同的属性,但值不同,就会发生合并冲突。
合并工具尝试将所有属性组合到同一元素中时可能出现的结果:
在这里插入图片描述

不过,在某些情况下,合并工具会采取其他行为方式以避免合并冲突:

  • 元素中的属性绝不会合并在一起,只会使用优先级最高的清单中的属性。

  • 和 元素中的 android:required 属性使用 OR
    合并,这样一来,如果发生冲突,系统将应用 “true” 并始终包含一个清单所需的功能或库。

  • 元素中的属性始终使用优先级较高的清单中的值,但以下情况除外:

    a.如果优先级较低的清单中的 minSdkVersion 值较高,那么除非您应用 overrideLibrary 合并规则,否则将会发生错误。
    b.如果优先级较低的清单中的 targetSdkVersion 值较低,合并工具将使用优先级较高的清单中的值,但也会添加所有必要的系统权限,以确保所导入的库继续正常运作(以防遇到较高的 Android 版本具有更多权限限制的情况)。如需详细了解此行为,请参阅有关隐式系统权限的部分。
    c.绝不会在清单之间匹配 元素。每个该元素都被视为唯一的元素,并添加到合并后的清单中的共同父元素中。

  • 对于属性之间的其他所有冲突,您将收到一条错误,并且必须指示合并工具如何解决该错误,方法是在优先级较高的清单文件中添加一个特殊属性(请参阅下面有关合并规则标记的部分)。

注意:
不依赖于默认属性值。简单来说,就是看谁属性设置了值的为准;由于所有唯一属性会组合到同一元素中,因此如果优先级较高的清单实际上依赖于某个属性的默认值而不声明该属性,则可能会导致意外结果。例如,如果优先级较高的清单不声明 android:launchMode 属性,则会使用默认值 “standard”;但如果优先级较低的清单声明此属性具有其他值,则该值将应用于合并后的清单(替换默认值)。因此,您应该将每个属性明确定义为您希望的值。(清单参考文档中介绍了每个属性的默认值。)
在这里插入图片描述

合并规则标记

合并规则标记是一个 XML 属性,可用于指定您对如何解决合并冲突或移除不需要的元素和属性的偏好。您可以对整个元素应用标记,也可以只对元素中的特定属性应用标记。

合并两个清单文件时,合并工具会在优先级较高的清单文件中查找这些标记。

所有标记都属于 Android tools 命名空间,因此您必须先在 元素中声明此命名空间:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp"
    xmlns:tools="http://schemas.android.com/tools">
节点标记

如需对整个 XML 元素(给定清单元素中的所有属性及其所有子标记)应用合并规则,请使用以下属性:

  • tools:node="merge"

    在没有冲突的情况下,使用合并冲突启发法合并此标记中的所有属性以及所有嵌套元素。这是元素的默认行为。
    在这里插入图片描述

  • tools:node="merge-only-attributes"

    仅合并此标记中的属性,不合并嵌套元素。
    在这里插入图片描述

  • tools:node="remove"
    从合并后的清单中移除此元素。虽然您似乎只需要删除此元素即可,但如果您发现合并后的清单中有不需要的元素,而且该元素是由不受您控制的优先级较低的清单文件(如导入的库)提供的,则必须使用此属性。
    在这里插入图片描述

  • tools:node="removeAll"
    与 tools:node=“remove” 类似,但它会移除与此元素类型匹配的所有元素(同一父元素内)。
    在这里插入图片描述

  • tools:node="replace"
    完全替换优先级较低的元素。也就是说,如果优先级较低的清单中有匹配的元素,会将其忽略并完全按照此元素在此清单中显示的样子使用它。
    在这里插入图片描述

  • tools:node="strict"

每当此元素在优先级较低的清单中与在优先级较高的清单中不完全匹配时,都会导致构建失败(除非已通过其他合并规则标记解决)。这会替换合并冲突启发式算法。例如,如果优先级较低的清单只是包含一个额外的属性,构建就会失败(尽管默认行为是将该额外属性添加到合并后的清单中)。
在这里插入图片描述

这会导致清单合并错误。在严格模式下,这两个清单元素不能有任何不同。因此,您必须应用其他合并规则标记解决这些差异。(通常,这两个元素会正常合并在一起,如上面的 tools:node=“merge” 示例中所示。)

属性标记

如需只对清单标记中的特定属性应用合并规则,请使用以下属性。每个属性可接受一个或多个属性名称(包括属性命名空间),属性名称之间用英文逗号分隔。

  • tools:remove="attr, …"
    从合并后的清单中移除指定属性。虽然您似乎只需要删除这些属性即可,但如果优先级较低的清单文件包含这些属性,而您想确保它们不会被纳入合并后的清单,则必须使用此属性。
    在这里插入图片描述
  • tools:replace="attr, …"

将优先级较低的清单中的指定属性替换为此清单中的属性。换句话说,始终保留优先级较高的清单中的值。
在这里插入图片描述

  • tools:strict="attr, …"

每当这些属性在优先级较低的清单中与在优先级较高的清单中不完全匹配时,都会导致构建失败。这是所有属性的默认行为,但具有特殊行为的属性除外,如合并冲突启发法中所述。
在这里插入图片描述
这会导致清单合并错误。您必须应用其他合并规则标记解决冲突。(切记:这是默认行为,因此如果您移除 tools:strict=“screenOrientation”,上面的示例将具有相同的结果。)

标记选择器

如果您想只对导入的某个特定库应用合并规则标记,请添加带有库软件包名称的 tools:selector 属性。

例如,对于下面的清单,只有在优先级较低的清单文件来自 com.example.lib1 库时,才会应用 remove 合并规则。
在这里插入图片描述

替换导入的库的

默认情况下,导入 minSdkVersion 值高于主清单文件的库时会出错,而且无法导入该库。如需使合并工具忽略此冲突并导入库,同时保留应用的较低 minSdkVersion 值,请将 overrideLibrary 属性添加到 标记。属性值可以是一个或多个库软件包名称(用英文逗号分隔),指明可以替换主清单的 minSdkVersion 的库。

例如,如果应用的主清单按如下方式应用 overrideLibrary:
在这里插入图片描述

合并策略

清单合并工具可以在逻辑上将一个清单文件中的每个 XML 元素与另一个文件中的对应元素相匹配。合并工具会使用“匹配键”匹配每个元素,匹配键可以是唯一的属性值(如 android:name),也可以是标记本身的自然唯一性(例如,只能有一个 元素)。如果两个清单具有相同的 XML 元素,则该工具会采用三种合并政策中的一种,将这两个元素合并在一起:

合并
将所有没有冲突的属性组合到同一标记中,并按各自的合并政策合并子元素。如果任何属性相互冲突,则使用合并规则标记将它们合并在一起。
仅合并子元素
不组合或合并属性(仅保留优先级最高的清单文件提供的属性),并按各自的合并政策合并子元素。
保留
将元素“按原样”保留,并将其添加到合并后的文件中的共同父元素中。只有在可以接受同一元素有多个声明时,才会采用此政策。
在这里插入图片描述在这里插入图片描述

具体更详细的清单合并请参考官网官网管理清单链接跳转

总结:
1.两个清单合并基本是按照OR来合并的,特殊属性除外;
2.两个清单合并时需要注意优先级;
3.相同属性如果设置的值不同会发生冲突,需要在高优先级的manifest清单中设置合并规则;
4.如果想让高优先级manifest直接替换低优先级manifest,可以在根节点直接设置节点标记tools:node=“replace”

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值