Android在打包的时候会合并清单文件,这里需要知道合并的原理,本文以

https://developer.android.com/studio/build/manifest-merge  官方文档为参考,进行翻译解读。同时也为自己记录相应的知识点。

合并优先级

清单文件合并是按照优先级进行合并的,低优先级的清单文件内容合并到高优先级的,假如合并的时候产生了冲突就需要解决冲突,这也是我们这篇文章重点要讲述的。而优先级的高低划分原则是这样的:

主工程(又区分构建体、渠道、风味) > module(按照依赖关系) > jar 包(aar)。

gradle的相关属性会覆盖manifest中的属性,比如最小sdk,minSdkVersion 属性会以gradle中的为准,所以manifest就不要写该属性

合并冲突

当低优先级的清单文件属性合并到高优先级中,假如高优先级中没有对应的属性,则直接合并,假如有并且不一样,这时候就有了冲突,应该去解决,怎么解决?

规则

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中的任何attribute 都可以使用补充规则,

<uses-permission android:name="android.permission.INTERNET"  tools:node="merge"/>
<uses-feature android:name="android.hardware.Sensor" tools:node="remove"/>
<uses-sdk android:targetSdkVersion="Q" tools:node="merge-only-attributes"/>
<permission android:name="xx" tools:node="replace"/>
<uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" tools:node="strict"/>
..........

常用的需要合并的属性值有 
 <uses-sdk> <uses-libray> <uses-feature> <targetSdkVersion> <minSdkVersion>.Android的解决方式是使用标记,合并工具会优先在高优先级的清单文件中寻找这些标记,这一点要记住。另外,在使用标记的时候,需要在根节点manifest中添加 tools 命名空间:

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

节点标记

merge tools:node = "merge/replace/strict/remove/removeAll/merge-only-attribute"

合并规则中很重要的一个规则是节点标记,而merge 是默认行为,当manifest 各节点属性没有声明节点标记时候,就会使用默认值。现在一一解释每个值的含义

  • merge  合并该attribute 所有的属性和子属性;
  • replace 替换其他的值,使用该清单文件的值(一般而言,都是替换掉低优先级的值)
  • strict    严格的意思,就是不同的清单文件,相同属性的值应该一样,否则编译失败。(一般而言,就是不同的清单文件同一个属性其值要一样)
  • remove  删除某个属性。
  • removeAll 删除某个属性及其嵌套的子属性。(相当于remove,不过是有些时候删除很多子属性时,方便一些)
  • merge-only-attribute :Merge attributes in this tag only; do not merge nested elements 。只合并属性,不合并嵌套的属性
主工程app 的testActivity 声明:<activity android:name=".testActivity" tools:node="merge"><meta-data android:name="xxx" tools:node="replace"/><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>module 的testActivity 声明:<activity android:name=".testActivity" ><meta-data android:name="xxx" tools:node="replace"/><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

说明:嵌套的含义——针对上面的activity(属于module)来说,就是activity里面的attribute——mate ,intent-filter,现在activity的合并标记是 merge,假如这个activity 所在的module、主工程都声明了该activity,显然在最终的manifest只会有一份 声明,需要合并(所以说出现在 manifest 的任何属性都可以运用合并标记)。这时候,我们需要按照规则来合并。

应用场景:

remove:假如主工程中不能使用某个权限,比如说联系人权限,但你引用的jar包或者aar使用了该权限,这时候就可以通过remove 标记去掉该权限在不影响使用的情况下。

replace:引用的工程在某个属性使用了和主工程不同的值,这时候使用replace可以解决冲突;

属性标记

tools:remove = "attr, ..."  tools:replace="attr, ..."  tools:strict="attr, ..."

见明知意。也是替换,移除,严格,和node中差不多,那为什么又搞出一个属性标记呢?为啥不直接用node这一个节点标记呢?
官方文档给出的解释:

To instead apply a merge rule only to specific attributes in a manifest tag, use the following attributes. Each attribute accepts one or more attribute names (including the attribute namespace), separated by commas.

低优先级<activity android:name="com.example.ActivityOne"android:windowSoftInputMode="stateUnchanged">高优先级<activity android:name="com.example.ActivityOne"
android:screenOrientation="portrait"   tools:remove="android:windowSoftInputMode">合并之后
<activity android:name="com.example.ActivityOne"    android:screenOrientation="portrait">

而其他的一些属性只有一个确定的子属性,比如前面提到的 user-feature \ permission 等等,他们都是确定好哪个属性了,所以就用了node 。

<uses-permission android:name="android.permission.INTERNET" tools:node="merge"/>
<uses-feature android:name="android.hardware.Sensor" tools:node="remove"/>

选择标记

应用场景:假如你只想对某个module 、library 实施一些规则,比如说,你引用了一个module, 一个aar ,你只想对aar包作用,这样你可以用selector 指明作用域(现在好像去掉了这个标记了,已经找不到了)

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

<uses-sdk>

场景1:假如依赖的jar 的minSdkVersion 大于主工程的值,这时候为了保持主工程的最小sdk值,可以使用

<uses-sdk android:minSdkVersion="15" tools:overrideLibrary="要覆盖的包名" />

注意:现在manifest 中的minSDK 和targetSdk会被gradle覆盖,不推荐再写 ,所以这里只需要填写

<uses-sdk  tools:overrideLibrary="要覆盖的包名" />

使用IDE 的合并工具

合并策略

合并工具通过寻找唯一的元素 (android:name ="") 或者 唯一的tag 比如<uses-sdk > ,按照如下总的规则去合并:

  1. 合并所有没有冲突的属性,若有冲突则按照冲突规则标记来;
  2. 只合并嵌套元素,比如activity 这种。
  3. 保持原来,并进行整和不同的属性值

下面看英文原文,上面的翻译不太准确:

Merge policies

The manifest merger tool can logically match every XML element from one manifest file to a corresponding element in another file. The merger matches each element using a "match key": either a unique attribute value (such as android:name) or the natural uniqueness of the tag itself (for example, there can be only one <supports-screen> element). If two manifests have the same XML element, then the tool merges the two elements together using one of three merge policies:

Merge

Combine all non-conflicting attributes into the same tag and merge child elements according to their respective merging policy. If any attributes conflict with each other, merge them together with the merge rule markers.

Merge children only

Do not combine or merge the attributes (keep only the attributes provided by the highest priority manifest file) and merge child elements according to their merging policy.

Keep

Leave the element "as is" and add it to the common parent element in the merged file. This is used only when it is acceptable for there to be several declarations of the same element.

 Manifest element merge policies and match keys

Element Merge policy Match key
<action> Merge android:name attribute
<activity> Merge android:name attribute
<application> Merge There is only one per <manifest>
<category> Merge android:name attribute
<data> Merge There is only one per <intent-filter>
<grant-uri-permission> Merge There is only one per <provider>
<instrumentation> Merge android:name attribute
<intent-filter> Keep No matching; several declarations within the parent element are allowed
<manifest> Merge children only There is only one per file
<meta-data> Merge android:name attribute
<path-permission> Merge There is only one per <provider>
<permission-group> Merge android:name attribute
<permission> Merge android:name attribute
<permission-tree> Merge android:name attribute
<provider> Merge android:name attribute
<receiver> Merge android:name attribute
<screen> Merge android:screenSize attribute
<service> Merge android:name attribute
<supports-gl-texture> Merge android:name attribute
<supports-screen> Merge There is only one per <manifest>
<uses-configuration> Merge There is only one per <manifest>
<uses-feature> Merge android:name attribute (if not present, then the android:glEsVersion attribute)
<uses-library> Merge android:name attribute
<uses-permission> Merge android:name attribute
<uses-sdk> Merge There is only one per <manifest>
Custom elements Merge No matching; these are unknown to the merger tool so they are always included in the merged manifest

Android 合并清单文件 Merge multiple manifest files相关推荐

  1. Android Studio清单文件合并规则

    使用Android Studio和基于Gradle的构建时,一个应用可能会有多个清单文件(AndroidManifest.xml)存在,比如src/main目录下的清单文件,library模块中的清单 ...

  2. Android Developer:合并清单文件

    使用Android Studio并且基于Gradle构建,每个App能在多个位置包含清单文件,例如在src/main文件夹下productFlavor.库.Android ARchive(AAR) b ...

  3. Android AndroidManifest 清单文件以及权限详解

    原文转自 http://my.oschina.net/yuanxulong/blog/366753 感谢作者 搬到自己博客方便查看. 每个Android应用都需要一个名为AndroidManifest ...

  4. Android应用清单文件:AndroidManifest.xml

    AndroidMainfest.xml清单文件是每个Android项目所必需的,它是整个Android应用的全局描述文件. <?xml version="1.0" encod ...

  5. Android 学习 《一》Multiple dex files define Landroid/support/design/widget/CoordinatorLayout$1;

    下午刚刚运行的android项目突然报错, Error:Execution failed for task ':app:transformClassesWithDexForDebug'. com.an ...

  6. Android合并音频文件

    [java] view plaincopy /** * 需求:将两个amr格式音频文件合并为1个 * 注意:amr格式的头文件为6个字节的长度 * @param partsPaths       各部 ...

  7. Android中清单文件引入配置参数,Android 使用gradle打包的各种配置

    原标题:Android 使用gradle打包的各种配置 在AS中利用gradle打包,可以高效并且自由地配置各种参数,发布不同的版本.关于配置gradle文件的一些做法,总结为如下. 一.替换Andr ...

  8. android 功能清单文件夹,全新Android L大小全部功能清单整理

    今天凌晨,谷歌在美国旧金山发布全新安卓系统 Android L,该系统预计今年秋季发布,在此之前先向开发者提供. 在凌晨的主题演讲中,谷歌表示全新安卓系统将为用户提供全新的使用体验,比如 Projec ...

  9. Android的清单文件添加百度地图SDK

    一.http://lbsyun.baidu.com/登录自己百度帐号 二.开发文档,Android地图SDK 三.创建应用 四.填写信息 五.复制并替换KEY

最新文章

  1. 激活函数sigmoid和激活函数softmax
  2. targetSdkVersion
  3. leetcode 850. Rectangle Area II | 850. 矩形面积 II(递归分割未重叠矩形)
  4. nyoj_218_Dinner_201312021434
  5. mysql 双机备份_mysql双机热备详解及延伸备份
  6. java代码安全检测机制,Java语言有多种实现的机制,下列( )技术不属于代码安全检测。...
  7. Django如何让未登录的用户自动跳转至登录页
  8. loss函数之L1Loss,MSELoss,SmoothL1Loss, HuberLoss
  9. .net环境下如何使用MySql数据库
  10. Java 常用对象-System类
  11. windows下成功安装XGBOOST
  12. vb.net的socket编程
  13. 信息系统安全等级保护 备案表
  14. SQL SERVER2008 R2 ,求教,故障日志不断增大,撑爆硬盘,谢谢。
  15. IIC上拉电阻的注意事项
  16. Windows 下的 Vim 编程
  17. C:\WINDOWS\system32\Macromed\Flash\Flash32_11_5_502_110.ocx
  18. 动物棋制作(C语言)
  19. c语言怎么描述逢2进1,C语言之进制
  20. Duplicated tag: ‘mirrors‘ (position: START_TAG seen ...erred\r\n

热门文章

  1. 记录一些常用工具类方法
  2. JVM异常不打印堆栈信息 [ -XX:-OmitStackTraceInFastThrow ]
  3. 算法训练营 重编码_我在编码训练营中的经验(以及是否适合您)
  4. 音视频学习笔记1--音视频基础知识(1)
  5. Real-Time Rendering Fourth Edition读书笔记1
  6. Demo( the fourth week)
  7. 曾谨言量子力学教程第3版笔记和课后答案
  8. Zookeeper 面试题及答案
  9. 各种插值法的python实现
  10. keep-alive原理