构建-9 合并清单文件 Merge

官方文档

合并多个清单文件

Merge multiple manifest files

APK 文件只能包含一个 AndroidManifest.xml 文件,但 Android Studio 项目 may contain several provided by the main source set, build variants, and imported libraries。因此,在构建应用时,Gradle 构建会 merges all manifest files into a single manifest file that‘s packaged into your APK。

清单合并工具通过遵循某些合并启发式算法[merge heuristics],并遵守您通过特殊 XML 属性定义的合并首选项,来合并各个文件中的所有 XML 元素 。 本页介绍清单合并的工作方式以及如何应用合并首选项来解决合并冲突。

提示: 使用 Merged Manifest view 预览合并清单的效果并找出冲突错误。

1

1

1

提示: 使用 Merged Manifest view 预览合并清单的效果并找出冲突错误。

合并优先级

Merge priorities

合并工具根据每个清单文件的优先级将所有清单文件按顺序合并到一个文件中。 例如,如果您有 3 个清单文件,则会先将优先级最低的清单合并到优先级第 2 高的清单中,然后再将合并后的清单合并到优先级最高的清单中(如图 1 所示)。

图 1. 合并 3 个清单 文件(从优先级最低的文件(左)合并至优先级最高的文件(右))的流程

有 3 种基本的清单文件可以互相合并,它们的合并优先级如下(按优先级由高到低的顺序):

  • 1、Manifest file for your build variant
    • 如果您的变体有多个源集,则其清单优先级如下:
      • Build variant manifest (such as src/demoDebug/)
      • Build type manifest (such as src/debug/)
      • Product flavor manifest (such as src/demo/)
    • 如果您使用的是 flavor dimensions,清单优先级将与每个维度在 flavorDimensions 属性中的列示顺序(按优先级由高到低的顺序排列)对应。
  • 2、Main manifest file for the app module
  • 3、Manifest file from an included library
    • 如果您有多个库,则其清单优先级与依赖顺序(库出现在 dependencies 块中的顺序)匹配。

For example, a library manifest is merged into the main manifest, then the main manifest is merged into the build variant manifest.

重要说明: build.gradle 文件中的构建配置将替换合并清单文件中的任何对应属性。 例如,build.gradle 文件中的minSdkVersion 将替换<uses-sdk> 清单元素中的匹配属性。为了避免混淆,您只需省去 <uses-sdk> 元素并在 build.gradle 文件中定义这些属性。For more details, see Configure Your Build.

1

1

1

重要说明: build.gradle 文件中的构建配置将替换合并清单文件中的任何对应属性。 例如,build.gradle 文件中的minSdkVersion 将替换<uses-sdk> 清单元素中的匹配属性。为了避免混淆,您只需省去 <uses-sdk> 元素并在 build.gradle 文件中定义这些属性。For more details, see Configure Your Build.

合并冲突启发式算法

Merge conflict heuristics

合并工具可以在逻辑上将一个清单中的每个 XML 元素与另一个清单中的对应元素相匹配。

如果优先级较低的清单中的元素与优先级较高的清单中的任何元素均不匹配,则该元素将被添加至合并清单。 但是,如果有匹配元素,则合并工具会尝试将其中的所有属性合并到相同元素中。如果工具发现两个清单包含相同属性,但值不相同,则会出现合并冲突。

下表 1 描述了合并工具尝试将所有属性合并到同一元素时可能出现的结果。

High
priority attribute
Low priority
attribute
Attribute‘s
merged result
No value No value No value (use default value)
Value B Value B
Value A No value Value A
Value A Value A
Value B Conflict error—you must add
a merge rule marker

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

  • <manifest> 元素中的属性绝不合并—仅使用优先级最高的清单中的属性。
  • <uses-feature> and <uses-library> 元素中的 android:required 属性使用 OR 合并,因此如果出现冲突,系统将应用 "true" ,并且 the feature or library required by one manifest is always included。
<uses-feature
	android:name="android.hardware.camera"
	android:required="false"/>

3

3

1

<uses-feature

2

    android:name="android.hardware.camera"

3

    android:required="false"/>
  • <uses-sdk> 元素始终使用优先级较高的清单中的值,但以下情况除外:
    • 如果低优先级清单的 minSdkVersion 值较高,an error occurs unless you apply the overrideLibrary merge rule。
    • 如果低优先级清单的 targetSdkVersion 值较低,合并工具将使用高优先级清单中的值,但也会添加任何必要的系统权限,以确保所导入的库继续正常工作(适用于较高的 Android 版本具有更多权限限制的情况)。 如需了解有关此行为的详细信息,请参阅有关隐式系统权限[implicit system permissions]的部分。
  • <intent-filter> 元素绝不会在清单之间匹配。Each is treated as unique and is added to the common parent element in the merged manifest.

对于属性之间的所有其他冲突,您将收到一则错误,并且必须通过在高优先级清单文件中添加特殊属性来指示合并工具如何解决此错误。

Do not depend on default attribute values.
由于所有 unique attributes 都合并到同一元素中,如果高优先级清单实际上依赖于属性的默认值而不需要声明,则可能会导致意外结果。
例如,如果高优先级清单不声明 android:launchMode 属性,则会使用 "standard" 的默认值;但如果低优先级清单声明此属性具有其他值,该值将应用于合并清单(替代默认值)。
因此,您应该按期望明确定义每个属性。(每个属性的默认值都会记录在 Manifest reference 中)。

4

4

1

Do not depend on default attribute values.

2

由于所有 unique attributes 都合并到同一元素中,如果高优先级清单实际上依赖于属性的默认值而不需要声明,则可能会导致意外结果。

3

例如,如果高优先级清单不声明 android:launchMode 属性,则会使用 "standard" 的默认值;但如果低优先级清单声明此属性具有其他值,该值将应用于合并清单(替代默认值)。

4

因此,您应该按期望明确定义每个属性。(每个属性的默认值都会记录在 Manifest reference 中)。

合并规则的标记

Merge rule markers

合并规则标记是一个 XML 属性,可用于表达您对关于如何解决合并冲突或删除不需要的元素和属性的首选项。 您可以对整个元素或只对元素中的特定属性应用标记。

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

所有标记均属于 Android tools 命名空间,因此您必须先在 <manifest> 元素中声明此命名空间,如下文所示:

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

3

3

1

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

2

    package="com.example.myapp"

3

    xmlns:tools="http://schemas.android.com/tools">

节点标记 Node markers

向整个 XML 元素(给定清单元素中的所有元素及其所有子标记)应用合并规则

merge

如果使用合并冲突启发式算法时没有冲突,则合并此标记中的所有属性以及所有嵌套元素。This is the default behavior for elements.

merge-only-attributes

仅合并此标记中的属性,不合并嵌套元素。

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:windowSoftInputMode=”stateUnchanged”>
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

8

8

1

<activity android:name=”com.example.ActivityOne”

2

    android:windowSoftInputMode=”stateUnchanged”>

3

    <intent-filter>

4

        <action android:name="android.intent.action.SEND"/>

5

        <data android:type="image/*" />

6

        <category android:name="android.intent.category.DEFAULT"/>

7

    </intent-filter>

8

</activity>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”
    tools:node="merge-only-attributes”/>

3

3

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”

3

    tools:node="merge-only-attributes”/>

合并的清单结果:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”
    android:windowSoftInputMode=”stateUnchanged”/>

3

3

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”

3

    android:windowSoftInputMode=”stateUnchanged”/>

remove

从合并清单中删除此元素。Although it seems like you should instead just delete this element, using this is necessary when you discover an element in your merged manifest that you don‘t need, and it was provided by a lower-priority manifest file that‘s out of your control (such as an imported library).

低优先级清单:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”cow”
      android:value=”@string/moo”/>
  <meta-data android:name=”duck”
      android:value=”@string/quack”/>
</activity-alias>

6

6

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”cow”

3

      android:value=”@string/moo”/>

4

  <meta-data android:name=”duck”

5

      android:value=”@string/quack”/>

6

</activity-alias>

高优先级清单:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”cow”
      tools:node=”remove”/>
</activity-alias>

4

4

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”cow”

3

      tools:node=”remove”/>

4

</activity-alias>

合并的清单结果:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”duck”
      android:value=”@string/quack”/>
</activity-alias>

4

4

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”duck”

3

      android:value=”@string/quack”/>

4

</activity-alias>

removeAll

与 tools:node="remove" 类似,但它会删除同一父元素内与此元素类型相匹配的所有元素[all elements matching this element type]。

低优先级清单:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”cow”
      android:value=”@string/moo”/>
  <meta-data android:name=”duck”
      android:value=”@string/quack”/>
</activity-alias>

6

6

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”cow”

3

      android:value=”@string/moo”/>

4

  <meta-data android:name=”duck”

5

      android:value=”@string/quack”/>

6

</activity-alias>

高优先级清单:

<activity-alias android:name=”com.example.alias”>
  <meta-data tools:node=”removeAll”/>
</activity-alias>

3

3

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data tools:node=”removeAll”/>

3

</activity-alias>

合并的清单结果:

<activity-alias android:name=”com.example.alias”/>

1

1

1

<activity-alias android:name=”com.example.alias”/>

replace

完全替换低优先级元素。也就是说,if there is a matching element in the lower-priority manifest, ignore it and use this element exactly as it appears in this manifest.

低优先级清单:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”cow”
      android:value=”@string/moo”/>
  <meta-data android:name=”duck”
      android:value=”@string/quack”/>
</activity-alias>

6

6

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”cow”

3

      android:value=”@string/moo”/>

4

  <meta-data android:name=”duck”

5

      android:value=”@string/quack”/>

6

</activity-alias>

高优先级清单:

<activity-alias android:name=”com.example.alias”
    tools:node=”replace”>
  <meta-data android:name=”fox”
      android:value=”@string/dingeringeding”/>
</activity-alias>

5

5

1

<activity-alias android:name=”com.example.alias”

2

    tools:node=”replace”>

3

  <meta-data android:name=”fox”

4

      android:value=”@string/dingeringeding”/>

5

</activity-alias>

合并的清单结果:

<activity-alias android:name=”com.example.alias”>
  <meta-data android:name=”fox”
      android:value=”@string/dingeringeding”/>
</activity-alias>

4

4

1

<activity-alias android:name=”com.example.alias”>

2

  <meta-data android:name=”fox”

3

      android:value=”@string/dingeringeding”/>

4

</activity-alias>

strict

当此【元素】在低优先级清单中的情况与在高优先级清单中的情况不完全匹配[does not exactly match]时生成构建故障(除非已通过其他合并规则标记解决)。 这将 overrides 合并冲突启发式算法。 例如,如果低优先级清单仅包括 an extra attribute,则构建将会失败(而默认行为会向合并清单添加额外属性)。

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:windowSoftInputMode=”stateUnchanged”>
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

7

7

1

<activity android:name=”com.example.ActivityOne”

2

    android:windowSoftInputMode=”stateUnchanged”>

3

    <intent-filter>

4

        <action android:name="android.intent.action.SEND"/>

5

        <category android:name="android.intent.category.DEFAULT"/>

6

    </intent-filter>

7

</activity>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”
    tools:node="strict”/>

3

3

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”

3

    tools:node="strict”/>

This creates a manifest merge error.  两个清单元素在严格模式下 cannot differ at all。 因此,您必须应用其他合并规则标记来解决这些差异。(通常,这两个元素会完全地合并在一起,如以上 tools:node="merge" 示例所示)。

属性标记 Attribute markers

要改为仅向清单标记中的特定属性[specific attributes]应用合并规则,请使用属性标记。每个属性接受一个或多个属性名称(包括属性命名空间),并以逗号分隔。

remove

从合并清单中删除指定属性。 Although it seems like you could instead just delete these attributes, it‘s necessary to use this when the lower-priority manifest file does include these attributes and you want to ensure they do not go into the merged manifest.

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:windowSoftInputMode=”stateUnchanged”/>

2

2

1

<activity android:name=”com.example.ActivityOne”

2

    android:windowSoftInputMode=”stateUnchanged”/>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”
    tools:remove=”android:windowSoftInputMode”/>

3

3

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”

3

    tools:remove=”android:windowSoftInputMode”/>

合并的清单结果:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”/>

2

2

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”/>

replace

将低优先级清单中的指定属性替换为 此清单中的属性。 换言之,始终保持 高优先级清单的值。

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@oldtheme”
    android:exported=”false”
    android:windowSoftInputMode=”stateUnchanged”>

4

4

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@oldtheme”

3

    android:exported=”false”

4

    android:windowSoftInputMode=”stateUnchanged”>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@newtheme”
    android:exported=”true”
    android:screenOrientation=”portrait”
    tools:replace=”android:theme,android:exported”>

5

5

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@newtheme”

3

    android:exported=”true”

4

    android:screenOrientation=”portrait”

5

    tools:replace=”android:theme,android:exported”>

合并的清单结果:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@newtheme”
    android:exported=”true”
    android:screenOrientation=”portrait”
    android:windowSoftInputMode=”stateUnchanged”>

5

5

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@newtheme”

3

    android:exported=”true”

4

    android:screenOrientation=”portrait”

5

    android:windowSoftInputMode=”stateUnchanged”>

strict

当这些【属性】在低优先级清单中的情况与 在高优先级 清单中的不完全匹配时生成构建故障。This is the default behavior for all attributes, except for those with special behaviors as described in the merge conflict heuristics.

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”landscape”/>

2

2

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”landscape”/>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:screenOrientation=”portrait”
    tools:strict="android:screenOrientation”/>

3

3

1

<activity android:name=”com.example.ActivityOne”

2

    android:screenOrientation=”portrait”

3

    tools:strict="android:screenOrientation”/>

This creates a manifest merge error. 您必须应用其他合并规则标记来解决冲突。Remember: This is the default behavior, so the above example has the same result if you remove tools:strict="screenOrientation"

同时使用多个标记

您也可以对一个元素同时应用多个标记,如下所示。

低优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@oldtheme”
    android:exported=”false”
    android:allowTaskReparenting="true"
    android:windowSoftInputMode=”stateUnchanged”>

5

5

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@oldtheme”

3

    android:exported=”false”

4

    android:allowTaskReparenting="true"

5

    android:windowSoftInputMode=”stateUnchanged”>

高优先级清单:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@newtheme”
    android:exported=”true”
    android:screenOrientation=”portrait”
    tools:replace=”android:theme,android:exported”
    tools:remove=”android:windowSoftInputMode”>

6

6

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@newtheme”

3

    android:exported=”true”

4

    android:screenOrientation=”portrait”

5

    tools:replace=”android:theme,android:exported”

6

    tools:remove=”android:windowSoftInputMode”>

合并的清单结果:

<activity android:name=”com.example.ActivityOne”
    android:theme=”@newtheme”
    android:exported=”true”
    android:allowTaskReparenting="true"
    android:screenOrientation=”portrait”>

5

5

1

<activity android:name=”com.example.ActivityOne”

2

    android:theme=”@newtheme”

3

    android:exported=”true”

4

    android:allowTaskReparenting="true"

5

    android:screenOrientation=”portrait”>

标记选择器 Marker selector

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

例如,对于下面的清单,仅在低优先级清单文件来自 com.example.lib1 库时应用 remove 合并规则,如果低优先级清单来自其他源,系统将会忽略 remove 合并规则。

<permission android:name="permissionOne"
    tools:node="remove"
    tools:selector="com.example.lib1">

3

3

1

<permission android:name="permissionOne"

2

    tools:node="remove"

3

    tools:selector="com.example.lib1">

注:If you use this with one of the attribute markers, then it applies to all attributes specified in the marker.

overrideLibrary

Override <uses-sdk> for imported libraries,替换所导入库的 <uses-sdk>

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

例如,如果应用的主清单按如下所示应用 overrideLibrary:

<uses-sdk android:targetSdkVersion="22"
    android:minSdkVersion="2"
    tools:overrideLibrary="com.example.lib1, com.example.lib2"/>

3

3

1

<uses-sdk android:targetSdkVersion="22" 

2

    android:minSdkVersion="2"

3

    tools:overrideLibrary="com.example.lib1, com.example.lib2"/>

则下面这个清单(来自com.example.lib1)可以合并,并且不会出现与 <uses-sdk> 标记相关的错误,且合并清单将保留应用清单中的 minSdkVersion="2"。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.lib1">
   <uses-sdk android:minSdkVersion="4"/>
...

4

4

1

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

2

          package="com.example.lib1">

3

   <uses-sdk android:minSdkVersion="4"/>

4

...

隐式系统权限

Implicit system permissions

在最近的 Android 版本中,应用曾经可以自由访问的某些 Android API 已受系统权限限制。To avoid breaking apps that expect access to these APIs,最近的 Android 版本允许应用在无权限的情况下继续访问这些 API,前提是它们已将 targetSdkVersion 设置为低于添加限制的版本的值。此行为有效地向应用授予了隐式 权限,以允许访问 API。因此,这可能会对具有不同 targetSdkVersion 值的合并清单产生以下影响。

如果低优先级清单文件提供隐式权限的 targetSdkVersion 值较低,而且高优先级清单没有相同的隐式权限(由于其 targetSdkVersion 等于或高于添加限制的版本),合并工具将向合并清单显式添加系统权限。

例如,如果您的应用将 targetSdkVersion 设置为 4 或更高值,并且导入了将 targetSdkVersion 设置为 3 或更低值的库,合并工具会将 WRITE_EXTERNAL_STORAGE 权限添加至合并清单。 表 2 列出了可以添加至合并清单的所有可能权限。

注:如果您将应用的 targetSdkVersion 设置为 23 或更高值,则必须在应用尝试访问受这些权限保护的 API 时为任何危险权限执行运行时权限请求。 如需获得更多指导,请参阅使用系统权限。

1

1

1

注:如果您将应用的 targetSdkVersion 设置为 23 或更高值,则必须在应用尝试访问受这些权限保护的 API 时为任何危险权限执行运行时权限请求。 如需获得更多指导,请参阅使用系统权限。

表 2. 合并工具可添加至合并清单的权限列表

Lower-priority
manifest declares
Permissions
added to the merged manifest
targetSdkVersion is
3 or lower
WRITE_EXTERNAL_STORAGE,  READ_PHONE_STATE
targetSdkVersion is
15 or lower and using READ_CONTACTS
READ_CALL_LOG
targetSdkVersion is
15 or lower and using WRITE_CONTACTS
WRITE_CALL_LOG

检查合并清单并查找冲突

Inspect the merged manifest and find conflicts

即使在构建 APK 之前,也可以预览合并清单,具体方法是:在 Android Studio 中打开您的 AndroidManifest.xml 文件,然后单击编辑器底部的 Merged Manifest 选项卡。

Merged Manifest 视图在左侧显示合并清单的结果,在右侧显示每个合并清单文件的相关信息。

从低优先级文件中合并的元素在左侧以不同颜色突出显示,每种颜色的关键字在右侧的 Manifest Sources 下方指定。

属于构建的一部分但不构成元素或属性的清单文件列在右侧的 Other Manifest Files 下方。

要查看有关元素来源的信息,请在左侧单击元素,详细信息将显示在右侧的 Merging Log 下方。

  

 

 

如果发生任何冲突,它们将显示在右侧的 Merging Errors 下方,并且包含有关如何使用合并规则标记解决冲突的建议。错误也会打印在 Event Log 窗口中(请选择 View > Tool Windows > Event Log)。

如果您想要查看合并决策树的完整日志,则可以在【各个模块】的 build/outputs/logs/manifest-merger-buildVariant-report.txt 中查找该日志文件。

附录:合并策略

Appendix: Merge policies

清单合并工具可以在逻辑上[logically]将某个清单中的 every XML element 与其他清单中的对应元素[corresponding element]相匹配。 合并工具会使用“匹配关键字”[match key]匹配每个元素,匹配关键字可以是唯一的属性值(如 android:name)或标记本身的天然唯一性[the natural uniqueness of the tag itself](例如,只能有一个 <supports-screen> 元素)。 如果两个清单具有相同的 XML 元素,工具将采用三种合并策略中的一种来合并这两个元素:

  • 合并[Merge]:将所有非冲突属性合并到同一标记中[Combine all non-conflicting attributes into the same tag], 然后按其各自的合并策略合并子元素[merge child elements according to their respective merging policy]。 如果任何属性 相互冲突,请使用合并规则标记将它们合并在一起。
  • 仅合并子项[Merge children only]:不整合或合并属性[Do not combine or merge the attributes](仅保留优先级最高的清单文件提供的属性),并按照其合并策略 合并子项。
  • 保留[Keep]:将元素“按原样”保留[Leave the element "as is"] ,然后将其添加至合并文件中的同一父元素[add it to the common parent element in the merged file]。此策略仅在可接受相同元素的多个 声明时使用[it is acceptable for there to be several declarations of the same element]。

表 3. 清单元素合并策略和合并关键字[Manifest element merge policies and match keys]

元素 合并策略 合并关键字
<action> 合并 android:name 属性
<activity> 合并 android:name 属性
<application> 合并 每个 <manifest> 仅一个
<category> 合并 android:name 属性
<data> 合并 每个 <intent-filter> 仅 1
<grant-uri-permission> 合并 每个 <provider> 仅 1 个
<instrumentation> 合并 android:name 属性
<intent-filter> 保留 不匹配;允许父元素内的多个声明
<manifest> 合并 每个文件仅 1 个
<meta-data> 合并 android:name 属性
<path-permission> 合并 每个 <provider> 仅 1 个
<permission-group> 合并 android:name 属性
<permission> 合并 android:name 属性
<permission-tree> 合并 android:name 属性
<provider> 合并 android:name 属性
<receiver> 合并 android:name 属性
<screen> 合并 android:screenSize 属性
<service> 合并 android:name 属性
<supports-gl-texture> 合并 android:name 属性
<supports-screen> 合并 每个 <manifest> 仅 1 个
<uses-configuration> 合并 每个 <manifest> 仅 1 个
<uses-feature> 合并 android:name 属性(如果不存在,则使用 android:glEsVersion 属性)
<uses-library> 合并 android:name 属性
<uses-permission> 合并 android:name 属性
<uses-sdk> 合并 每个 <manifest> 仅 1 个
自定义元素 合并 无匹配;合并工具不了解这些信息,因此它们始终 包括在合并清单中

2018-7-24

原文地址:https://www.cnblogs.com/baiqiantao/p/9363208.html

时间: 2024-10-10 08:04:48

构建-9 合并清单文件 Merge的相关文章

Android清单文件合并的那些事

APK文件只能包含一个AndroidManifest.xml文件,但Android Studio项目可以包含多个文件(通过buildSrc.导入的库引入).因此,在构建应用时,Gradle构建会将所有清单文件合并到一个封装的APK的清单文件中. 清单文件合并优先级 清单合并工具 可以使用Merged Manifest视图预览合并清单的效果并找出冲突错误. 可以互相合并的基本清单文件,合并优先级如下(优先级由高到低): 清单文件构建变体 如果变体有多个源集,其清单优先级由高到低如下: a.构建变体

构建-13 Analyzer APK文件分析

官方文档 使用APK Analyzer分析您的构建 [Analyze your build with APK Analyzer] Android Studio包含一个APK分析器,可在构建过程完成后立即深入了解APK的组成.使用APK分析器可以减少您在应用中调试DEX文件和资源调试问题所花费的时间,并有助于减少您的APK大小.它也可以通过命令行apkanalyzer使用. 使用APK分析器,您可以完成以下操作: 查看APK中文件的绝对大小和相对大小,例如DEX和Android资源文件. 了解DE

git两种合并方法 比较merge和rebase

18:01 2015/11/18git两种合并方法 比较merge和rebase其实很简单,就是合并后每个commit提交的id记录的顺序而已注意:重要的是如果公司用了grrit,grrit不允许用merge,所以好像都是用rebase却别讲解,比如:在服务器上的develop分支有多人在开发,你们同时clone或pull下来最新代码,但是开发进度不一样,你在开发一个任务的时候其他人提交了编号为1,2的commit和push,你现在开发完了也要提交,你的提交编号是3,4(注意:编号不代表顺序现实

matlab批量合并txt文件

1: %% merge.m 2: %%%%Main程序%%%%%% 3: %%%%%% 4: %%%%%%本程序合并完各个子文件夹中的txt到主文件目录下,并且合并的文件以子文件夹名字命名 5: %%%%%%同时,每次合并时,如果主文件夹已存在某一个子文件夹名字A的txt文件,那么此次合并,将把当前 6: %%%%%%这个子文件夹A中所有的txt文件追加到子文件夹A.txt文件的末尾处. 7: clear; 8: clc; 9: % MainFolder='D:\Master-FTP\磁流变阻尼

合并PDF(Merge PDF)

插件介绍: 想必各位小伙伴们都会遇到这样的情况,在网上下载资料的时候,本来是完整的,下载完成后却被分成了几个部分,如果把这几个部分合成一个PDF文件,那么不管是阅读还是管理都会更方便,今天就给大家介绍这个合成PDF的插件.Smallpdf的PDF合并工具运行您免费在线合并PDF文件. 拖放或上传多个PDF文件,当文件正上传中,您可预备工作.一旦您满意该效果,即可生成PDF,然后该文件将自动下载至您的硬件. 使用说明: 将合并PDF(Merge PDF)添加至chrome,并在扩展器中启动它. 功

Hive 合并输入输出文件

如果HIVE的输入文件是大量的小文件,而每个文件启动一个map的话是对yarn资源的浪费,同样的,Hive输出的文件也远远小于HDFS块大小,对后续处理也是不利的 HIVE中支持通过参数调整输入和输出的文件大小 1.合并输入文件 set mapred.max.split.size=256000000;  #每个Map最大输入大小 set mapred.min.split.size.per.node=100000000; #一个节点上split的至少的大小 set mapred.min.split

HDFS 实际应用场景合并小文件

合并小文件,存放到HDFS上, 采取在向HDFS复制上传的过程中将小文件进行合并,效果会更好 package org.xueruan.hadoop.hdfs; import java.nio.file.Path; import sun.management.FileSystem; /* * function: merge file while copying and uploading files into HDFS */ public class PutMerge { public stati

Android的学习之路(四)项目中清单文件的学习和android中经常使用的显示单位

1.所谓的清单文件就是项目中的AndroidManifest.xml文件.这个文件但是有大用处的.比方:app的名字,图标.app支持的版本号app的包名等等.以下我就介绍下这个清单文件的各个參数的作用. <manifest xmlns:android="http://schemas.android.com/apk/res/android"命名空间 package="com.example.hello"包名唯一标示一个应用 android:versionCod

在AndroidManifest(清单文件)中注册activity(活动)及配置主活动、更改App图标、App名称、修改隐藏标题栏

打开app/src/main/AndroidManifest. 1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.administrator.myapplication" > 4 5 &