Android官方技术文档翻译——清单合并

2017-04-15 13:34:08

本文译自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,请点击文末的“顶”;如有错讹,敬请指正。谢谢。


清单合并

目录

  1. 清单文件顺序

  2. Android 清单文件合并

  3. 元素和属性的合并处理

    1. 3.9.1 合并

    2. 3.9.2 只合并子节点

    3. 3.9.3 总是合并

    4. 3.9.4 元素合并策略和key的列表

    5. 3.9.5 包名称智能替换

    6. 3.6.1 日志记录:

    7. 3.6.1.2.1 操作格式

    8. 3.6.1.2.2 示例:

    9. 3.6.1.1 消息

    10. 3.6.1.2 NodeRecord

    1. 3.5.1 tools:node 标记

    2. 3.5.2 tools:attr 标记

    3. 3.5.3 选择器(Selector)

    4. 3.5.4 tools:overrideLibrary 标记

    5. 3.1 隐含声明

    6. 3.2 自动升级

    7. 3.3 占位符支持

    8. 3.4 合并策略的常见描述

    9. 3.5 标记

    10. 3.6 日志

    11. 3.7 构建错误

    12. 3.8 Blame

    13. 3.9 合并策略

    1. 属性标记示例

      1. 4.1 重写来自库项目的属性

      2. 4.2 删除来自库项目的属性。

      3. 4.3 强制更新属性值

      4. 4.4 混合操作

    2. 元素标记示例

      1. 5.4.1 Main Manifest

      2. 5.1 移除元素

      3. 5.2 移除所有元素

      4. 5.3 元素替换

      5. 5.4 选择器示例


    本文档主要介绍新的清单合并工具。


    这个新的合并工具是gradle android 插件的 0.10 版中引入的。截至 0.11 版本,该 gradle 插件默认情况下都是使用此合并工具。


    如果想恢复使用旧的清单合并工具,可以在你的 build.gradle 中添加以下配置:

    android {
    useOldManifestMerger true

    }


    Manifest 文件排序


    一般情况下,有三种类型的清单文件需要合并成一个最终的应用程序清单,这里按照优先级顺序列出:

    1. Product flavors 和构建类型所指定的清单文件。

    2. 应用程序的主清单文件。

    3. 类库的清单文件。


    第一种类型的清单文件通常会重写清单的内容,因为它专门提供用于特定的交付的应用程序。然后,第三种类型的清单文件通常会被合并入上一步产生的主清单中。合并的规则取决于每个节点类型,可以使用“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 ,会查找以下的清单文件以进行合并

    1. x86/AndroidManifest.xml

    2. high/AndroidManifest.xml

    3. 15/AndroidManifest.xml

    4. 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},因为@符号已经预留给了

    • 2020-04-14 09:42:47

      用 TypeScript 编写 npm 模块

      自从开始使用 Node.js 已经一年多,写的代码越多,越是觉得自己提高的越慢。想来应该有没有将单一功能的代码封装在一个独立模块,而导致代码稍微多一点就维护困难的原因。

    • 2020-04-14 09:46:25

      TypeScript 入门教程

      TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。 TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

    • 2020-04-14 09:51:03

      package.json 字段说明

      package.json 有很多字段,也有很多官方字段,我们需要知道他们的具体是做什么的才能很好的运用

    • 2020-04-14 15:35:52

      caniuse前端兼容性检查和使用

      相信大家都曾用caniuse网站查询过css、js的一些兼容性问题,并且都从它反馈的兼容性数据中获益,让我们的线上项目更加稳定、和谐的跑在用户电脑里。不过对于caniuse页面上的一些细节,我们可能会感到困惑或者模棱两可,今天就带着大家一起来重新认识caniuse这个网站,并对它的原理和细节做些探究。

    • 2020-04-15 17:00:07

      export和import的理解,这一篇问扎根就够了

      在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

    • 2020-04-15 21:14:13

      .d.ts与.ts的区别 .d.ts怎么用

      在TypeScript项目中直接引入Javascript包是不能使用的,因为包中缺少TypeScript类型声明,如果是自己写的包,可以考虑自己增加一个.d.ts类型声明文件,如果代码比较多或者使用的是第三方的包,自己写就比较麻烦了。第三方的包首先考虑找一个别人写好的声明文件,如果没有可以使用一些自动生成声明文件的工具。