本文译自Android官方技术文档《Manifest Merger》,原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger。
翻译不易,转载请注明CSDN博客上的出处:
http://blog.csdn.NET/maosidiaoxian/article/details/42671999
翻译工作耗时费神,如果你觉得本文翻译得还OK,请点击文末的“顶”;如有错讹,敬请指正。谢谢。
清单合并
目录
本文档主要介绍新的清单合并工具。
这个新的合并工具是gradle android 插件的 0.10 版中引入的。截至 0.11 版本,该 gradle 插件默认情况下都是使用此合并工具。
如果想恢复使用旧的清单合并工具,可以在你的 build.gradle 中添加以下配置:
android {
useOldManifestMerger
true
}
Manifest 文件排序
一般情况下,有三种类型的清单文件需要合并成一个最终的应用程序清单,这里按照优先级顺序列出:
Product flavors 和构建类型所指定的清单文件。
应用程序的主清单文件。
类库的清单文件。
第一种类型的清单文件通常会重写清单的内容,因为它专门提供用于特定的交付的应用程序。然后,第三种类型的清单文件通常会被合并入上一步产生的主清单中。合并的规则取决于每个节点类型,可以使用“tools:”命名空间属性来更改。
由于多个product flavors和构建类型,这些清单文件合并的结果的组合可能会是一个矩阵。然而,对于每一个组装的步骤,每一个flavor group和构建类型的值都只能选择一个,导致出现了潜伏的覆盖主清单文件的清单文件的排序列表。
例如,下面的 FlavorGroups: abi,density,API,Prod/Internal 导致形成了以下可能的flavors的矩阵:
ABI | Density | API | Prod/Internal |
x86 | mdpi | 9 | prod |
arm | high | 14 | internal |
mips | xhigh | 15 | |
xxhigh |
这样就形成了3x4x3x2 种可能的组合。然而,对于每一次执行组装,只能是一个group里的falvor,定义在原始的 build.gradle 的flavor group 的属性形成了一个可能要合并的清单 文件的列表,并且这个列表由高优先级到低优先级排序。
例如,构建 x86-high-15-prod 的 variant ,会查找以下的清单文件以进行合并
x86/AndroidManifest.xml
high/AndroidManifest.xml
15/AndroidManifest.xml
internal/AndroidManifest.xml
在这个有序列表中,每个文件根据其在列表中的顺序都有一个优先级,合并工具将使用这个优先级来决定哪个XML元素或属性将覆盖一个较低优先级的设置。
因此,合并工具的输入将如下:
由flavor或编译类型的清单文件按优先级组成的有序列表,这些会被经常引用作为 flavors的清单。
主清单文件
由一些类库声明(或依赖传递而有的)的清单文件组成的有序列表。
用于占位符和XML产生的注入值
Android 清单文件合并
在一个清单文件中的每个元素都可以根据它的元素类型(比如activity,intent-filter)和一个可选的键值(key value)来识别。一些元素,如“activity”,必须有一个key,因为在一个AndroidManifest.xml中可能存在多个这样的元素。其他的元素,像“application”,就不要求一定要有一个key,因为只能有一个这样的元素。
元素的类型和键值对代表了一个清单元素的身份。
合并的activity的始终是两个相同类型的元素之间,一个来自更高优先级的清单文件,一个来自较低优先级的清单文件。每一个合并的activity都有一个默认的行为,这一点将在随后进行描述。此外,在节点或一个指定的属性上的每个默认合并的activity都可能会被including工具的指定标记所覆盖。
合并过程中还会把对每一个节点的合并结果记录下来,这将在“日志”章节描述。
元素和属性的合并过程
隐式声明
一些属性都会有默认值(默认定义在在线 文档中)。当一个较高优先级的元素没有定义默认值为X的属性时,如果一个较低优先级的元素也恰好定义了一个值同样是X的属性,那么这个属性仍然会被添加到合并的元素中 (当然它的值是X), 因为它表示了类库对这个属性的值的一个明确的选择,从而不去考虑把默认值作为它的值,而是为某特性设置一个正确的值(以防默认值发生改变)。
大多数有默认值的属性,如果在低优先级的属性中已经定义了值,那么默认值将被manifest合并工具忽略;定义的值会被合并,因为在默认值 和一个设置的值之间,并没有冲突。在生成的合并的元素中,这个属性会被设置为设定的值。
然而,下面列出的几种情况例外:
<uses-feature android:required> | 默认值为 true。在与其他属性合并时,将使用“或”的合并策略。这时因为如果任何一个库需要该特性,那么生成的应用程序也将需要此特性。 |
<uses-library android:required> | 同 uses-feature:required。 |
<uses-sdk android:minSdkVersion> | 默认值为 1。 将使用更高优先级文件的版本,但导入一个较新版本的库时将会产生错误。 |
<uses-sdk android:maxSdkVersion> | 同 uses-sdk:minSdkVersion |
<uses-sdk android:targetSdkVersion> | 同 uses-sdk:minSdkVersion |
自动升级
当导入一个target SDK 版本比项目低的库时,它可能需要显式声明地授予权限 (可能还需要进行其他更改),以使得类库在以后运行时能正常运行。这将由清单合并工具自动进行。
占位符支持
当属性值包含一个占位符 (见下面的格式)时,合并工具将把此占位符的值换成一个注入的值。注入的值是在build.gradle里面定义的。
占位符值的语法是 ${name},因为@符号已经预留给了