每个app 或 module 或 组件 都会包含一个manifest文件,即AndroidMnifest.xml
,用于配置当前的 app 或 module 或 组件的各方面信息。然而,最终构建成APK时,会合并成一个AndroidManifest文件。
那么,manifest文件是怎么合并的呢?
1. 合并冲突规则(merge conflict rules)
合并冲突,是指多个Manifest文件中含有同一属性但值不同时,默认合并规则解决不了从而导致的冲突。
合并的优先级从高到低依次是:
buildType下的Manifest设置
productFlavor下的Manifest设置
主工程src/main
dependency | module | library
属性的高低优先级合并结果:
属性的高低优先级合并结果
当然还存在例外情况:
-
uses-feature android:required和uses-library android:required默认值都是true,根据OR规则合并
-
如果不指定uses-sdk,默认的minSdkVersion和targetSdkVersion值为1,当发生冲突时将使用高优先级的值。若不指定targetSdkVersion,其值等于targetSdkVersion
-
当library工程的minSdkVersion比主工程src/main中的minSdkVersion低时会产生冲突,此时需要添加overLibrary标记解决冲突
-
当library工程的targetSdkVersion比主工程src/main中的大时,合并过程会增加一些权限保证library工程能正常运行
-
每个Manifest文件只和其子Manifest文件的属性合并
-
<intent-filter>的合并规则是叠加而不是覆盖
2. 合并冲突标记和选择器(merge conflict marker&selector)
合并冲突标记,是android tools namespace中的一个属性,用来解决默认冲突规则解决不了的冲突。
主要包含以下几个:
merge
: 默认合并操作。
replace
: 高优先级替换低优先级Manifest文件中的属性
strict
: 属性相同而值不同时会报错,除非通过冲突规则resolved
merge-only
: 仅合并低优先级的属性
remove
: 移除指定的低优先级的属性
remove-All
: 移除相同节点类型下所有低优先级的属性
注: 节点层面默认使用merge,属性层面默认使用strict
3. 一些常用场景
- application中移除低优先级的theme设置,替换低优先级的name、icon、label等属性;
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.merlin.sample">
<application
tools:remove="theme"
tools:replace="name,icon,label"
- uses-sdk 覆盖低优先级的设置 (默认情况下是不允许低优先级的minSdkVersion大于高优先级的,否则会报错。)
<uses-sdk
android:targetSdkVersion="23"
tools:overrideLibrary="com.sample.library" />
(部分内容参考于http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0216/3968.html
,如有不妥,请联系删除~)
网友评论