Android Developer:合并清单文件
使用Android Studio而且基于Gradle构建。每一个App能在多个位置包括清单文件,比如在src/main文件夹下productFlavor、库、Android ARchive(AAR) bundles of Android Library项目,和第三方依赖。在构建过程中。包括在你的app中的多个AndroidMainfest.xml设置合并成一个,生成APK清单文件用于app的打包和公布。
清单文件的设置基于清单优先级来合并。取决于清单文件的位置。从制定build variant清单文件的元素,属性,和子元素构建合并你的app清单文件。
合并冲突规则
------------------------------------------------------------------
合并的冲突发生在清单文件包括同样的清单元素,而且有不同的属性值,无法使用默认的合并规则解决的时候。Conflict markers和selectors也能定义自己定义的合并规则。比如同意一个导入的库有一个minSdkVersion大于在其他更高优先级清单中定义的版本号。
清单合并优先级决定了哪个清单设置在合并冲突中保留。使用高优先级订单文件设置覆盖低优先级清单。以下的列表具体描写叙述了在合并过程中。哪个清单设置的优先级最高:
最高优先级:buildType清单设置
高优先级:productFlavor清单设置
中优先级:app项目在src/main/文件夹下清单
低优先级:依赖和库清单设置
清单冲突合并基于以下的合并规则在XML节点和属性级别被解决:
清单合并规则例外:
uses-feature android:required;和use-library android:required元素默认值为true。而且使用一个或者合并。这样不论什么要求的功能和库在成成的APK都被包括。
假设没有声明,<uses-sdk>元素,minSdkVersion和targetSdkVersion。默认的值为1。当合并冲突发生,更高优先级的清单文件值被使用;
导入一个包括minSdkVersion值高于app的src/main/清单文件。清单产生一个错误。除非overrideLibrary冲突记号被使用;
注意:假设没有明白的声明,targetSdkVersion默觉得minSdkVersion值。当没有元素在不论什么清单文件或者build.gradle文件里出现的时候,minSdkVersion默觉得1。
当导入一个包括targetSdkVersion值低于app的src/main清单文件的库,清单合并过程明白授予权限并。并确保正确的导入库库函数。
manifest元素只合并孩子清单元素。
intent-filter元素从不改变而且总是加入到合并的清单同样的父节点下。
重要:在清单文件被合并后,构建过程使用build.gradle文件里的不论什么设置覆盖终于的清单设置。很多其他详情,请阅读Configure Gradle Builds。
合并冲突标记和选择器
------------------------------------------------------------------
清单标记和选择器通过制定冲突解决的方法覆盖默认的规则。比如,使用冲突标识来合并一个库清单的minSdkVersion高于更高优先级清单,或者合并清单同样的Activity,可是不同的android:theme值。
合并冲突标识
一个合并冲突标识是一个在Android工具空间的指定元素。它定义了一个指定的冲突合并方案。创建一个冲突标识是为了避免使用默认合并规则没有解决的合并冲突错误。支持的合并冲突标识包括:
merge
当没有合并规则冲突的时候合并属性。
默认的合并动作。
replace
使用高优先级的清单替代低优先级清单中的属性;
strict
merge-only
同意指定低优先级属性的合并动作。
remove
删除合并后的清单指定的低级别元素;
remove-All
删除合并后清单的同样节点类型的全部低优先级元素。
默认情况下。清单的合并过程在节点级别应用merge冲突标识。
全部声明的清单属性默认是strict合并策略。
为了设置一个合并冲突标识,首先在AndroidManifest.xml文件里声明命名空间。
然后在清单中输入合并冲突标识的一个指定的合并冲突动作。这个样例插入了replace标识来设置一个replace动作,来解决在android:icon和android:lable清单元素的冲突。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tests.flavorlib.app"
xmlns:tools="http://schemas.android.com/tools"> <application
android:icon="@drawable/icon"
android:label="@string/app_name"
tools:replace="icon, label">
...
标记属性
冲突标识使用tools:node和tools:attr属性来在XML节点或者属性级别的冲突动作。
tools:attr标识只使用restrict,remove,和replace合并动作。多个tools:attr标识的值能够被应用到一个指定的元素。比如,使用tools:replace="icon,lable,theme"来提来更低的优先级icon。lable和theme属性。
向清单文件里注入构建值
-----------------------------------------------------------------
清单文件合并也能使用清单占位符。从build.gradle文件向清单属性注入属性值。
清单占位符使用这个语法${name}设置属性值,name是注入build.gradle属性,build.gradle文件使用manifestPlaceholders属性来定义占位符的值。
注意:在app中未解析的占位符名称会导致构建失败。
在库中未解析的占位符生成警告。而且将这个库导入一个app的时候必须解决。
这个样例展示了清单占位符${applcationId}用于映射build.gradle的applicationID属性值到android:name属性值。
注意:Android Studio为build.gradle applicationID值提供了一个默认的${applicationId}占位符,它不显示在构建文件里。当为库模块构建一个AAR(Android ARchive)包时。不须要在清单合并设置中提供一个自己主动的@{applicationID}占位符。相反,使用一个不同的占位符,比如@{libApplicationID}。并为假设你想包括归档库的appliction Id,为它提供一个值。
清单实体:
<activity
android:name=".Main">
<intent-filter>
<action android:name="${applicationId}.foo">
</action>
</intent-filter>
</activity>
构建文件:
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
productFlavors {
flavor1 {
applicationId = "com.mycompany.myapplication.productFlavor1"
}
}
合并清单值:
<action android:name="com.mycompany.myapplication.productFlavor1.foo">
清单文件占位符和构建文件manifestPlaceholders属性能被用于注入其他清单文件值。
对于applicationId依赖的属性。manifestPlaceholders属性明白的在build.gradle文件里声明。
这个样例展示了清单占位符注入activityLabel值。
Gradle build 文件:
android {
defaultConfig {
manifestPlaceholders = [ activityLabel:"defaultName"]
}
productFlavors {
free {
}
pro {
manifestPlaceholders = [ activityLabel:"proName" ]
}
}
构建文件:
android {
defaultConfig {
manifestPlaceholders = [ activityLabel:"defaultName"]
}
productFlavors {
free {
}
pro {
manifestPlaceholders = [ activityLabel:"proName" ]
}
}
在清单文件里的占位符:
<activity android:name=".MainActivity" android:label="${activityLabel}" >
注意:占位符的值支持部分值注入,比如android:authority="com.acme.${localApplicationId}.foo".
通过Product Flavor组合并清单文件
-----------------------------------------------------------------
当使用GroupbleProductFlavor属性。不论什么在Product flavor组的清单文件的合并优先级取决于在构建文件里的排列顺序。清单文件合并的过程基于build variant的构建配置,为product flavor组创建一个单独合并清单文件。
比如,假设一个build varian从各自的product flavor组ABI,Density,API和Prod參考了product flavors x86,mdpi,21,和paid,在build.gradle文件里以该顺序排列。然后清单文件以product flavors在构建文件里排列的顺序为优先级合并。
为了说明这个样例,以下的标识展示了每一个product flavor组列举了什么product flavor。
这个product flavors和组的组合定义了build variant。
|
Product Flavor Group |
Product Flavor |
|
ABI |
x86 |
|
density |
mdpi |
|
API |
22 |
|
prod |
paid |
清单合并顺序:
prod-paid AndroidManifest.xml(低优先级)合并到API-22 AndroidManifest.xml
API-22 AndroidManifest.xml合并到density-mpi AndroidManifest.xml
density-mpi AndroidManifest.xml合并到ABI-x86 AndroidManifest.xml(高优先级)
隐式权限
-----------------------------------------------------------------
导入一个支持隐式授予权限的Android执行的库,可能会自己主动往合并清单中加入这个权限。比如,假设一个targetSdkVersion为16的应用程序,导入一个targetSdkVersion为2的库。Andorid Studio加入WRITE_EXTERNAL_STORAGE权限,以确保跨SDK版本号的兼容性。
注意:很多其他如今的Android版本号代替隐式的权限声明。
|
Importing this library version |
Declares this permission in the manifest |
|
targetSdkVersion < 2 |
WRITE_EXTERNAL_STORAGE |
|
targetSdkVersion < 4 |
WRITE_EXTERNAL_STORAGE,READ_PHONE_STATE |
|
Declared WRITE_EXTERNAL_STORAGE |
READ_EXTERNAL_STORAGE |
|
targetSdkVersion < 16 and using the READ_CONTACTS permission |
READ_CALL_LOG |
|
targetSdkVersion < 16 and using WRITE_CONTACTS permission |
WRITE_CALL_LOG |
处理清单合并构建错误
------------------------------------------------------------------
在构建过中,清单合并过程在模块的build/outputs/logs文件夹下mainfest-merge-<productFlavor>-report.txt文件里记录了每一个合并事务。
每一个模块的build variants生成不同的日志文件。
当一个清单合并构建发生错误的时候,构建过程在日志文件里记录了描写叙述合并冲突错误消息。比如,在以下的清单之间导致了一个构建错误android:screenOrientation合并冲突。
高优先级的清单声明:
<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="portrait"
android:theme="@theme1"/>
低优先级的清单声明:
<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="landscape"/>
错误日志:
/project/app/src/main/AndroidManifest.xml:3:9 Error:
Attribute activity@screenOrientation value=(portrait) from AndroidManifest.xml:3:9
is also present at flavorlib:lib1:unspecified:3:18 value=(landscape)
Suggestion: add 'tools:replace="icon"' to element at AndroidManifest.xml:1:5 to override
Android Developer:合并清单文件的更多相关文章
- -Gradle 翻译 Merge AndroidManifest 合并清单文件 MD
目录 目录 Merge AndroidManifest 合并清单文件 合并多个清单文件 合并优先级 合并冲突启发式算法 合并规则的标记 节点标记 属性标记 Attribute markers 标记选择 ...
- Android Studio中清单文件改versionCode和versionName没效果的原因
在Android Studio中,项目的versionCode 和versionName 的控制不是在AndroidManifest.xml清单文件中更改的,而是在项目的build.gradle中更改 ...
- Android清单文件合并的那些事
APK文件只能包含一个AndroidManifest.xml文件,但Android Studio项目可以包含多个文件(通过buildSrc.导入的库引入).因此,在构建应用时,Gradle构建会将所有 ...
- ionic2+集成第三方sdk时,合并多个清单文件的方法
具体方案android studio官网上已经给出,但需要架梯子,所以这篇文章直接把它搬到墙内,方便查看: 合并多个清单文件 合并优先级 合并冲突启发式算法 合并规则标记 节点标记 属性标记 标记选择 ...
- Android系统编程入门系列之清单文件
在上一篇文章中已经提到,Android系统加载应用程序之后,首先会读取该应用程序的AndroidManifest.xml清单文件,之后根据该清单文件加载后边的东西.所以要开发应用程序,自然要先知道清单 ...
- Android开发学习清单
目录: 第1章 Android应用与开发环境1.1 Android的发展和历史1.1.1 Android的发展和简介1.1.2 Android平台架构及特性1.2 搭建Android开发环境1.2.1 ...
- Android多版本flavor配置之资源文件和清单文件合并介绍
知识背景 Android studio升级到3.0之后,gradle增加了多维度管理配置,便于同一个项目中创建应用的不同版本,分别管理依赖项并签署配置.创建产品风味与创建构建类型类似:只需将它们添加到 ...
- Android清单文件详解(三)----应用程序的根节点<application>
<application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...
- Android AndroidManifest 清单文件以及权限具体解释
每一个Android应用都须要一个名为AndroidManifest.xml的程序清单文件,这个清单文件名称是固定的而且放在每一个Android应用的根文件夹下.它定义了该应用对于Android系统来 ...
随机推荐
- [BZOJ1054][HAOI2008]移动玩具 bfs+hash
1054: [HAOI2008]移动玩具 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2432 Solved: 1355[Submit][Stat ...
- poj2181 jumping cow
umping Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7579 Accepted: 4559 Descr ...
- Web前端培训学习心得
web前端工程师技术日趋成熟,越来越多的行业巨头正不断向web前端工程师示好,在未来几年,web前端将会以更多的形式渗透到我们生活中的方方面面,因此越来越多的从业者开始关注web前端开发行业,今天小编 ...
- (1)powershell使用帮助
一.更新下载帮助 初始powershell是没有文档的,需要用指令更新下载到本地 管理员运行 update-help 好像有的模块需要FQ才能下载 ?? 帮助文档的开源地址 github.com/p ...
- ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树 + 永久标记)
题目链接 ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. ...
- python 设计模式之代理模式
代理模式在一般形式上是一个类函数接口.代理可以是这些事物的接口:网络连接,存储的对象,文件,或者其他资源(昂贵的或者不容易复制的). 一个众所周知的代理模式的例子就是引用计数的指针对象. 代理模式是结 ...
- 《Flex 第一步》
//什么是FlexFlex 是一个针对企业级富互联网应用的表示层解决方案.具体地说,Flex是一种应用程序框架.富互联网应用程序,Rich Internet Application,简称RIA,将桌面 ...
- Makefile学习之通配符和自动变量
规则中的通配符 “*” ,“?” ,“ [...]”, " % " , " wildcard " 1.“*” *.c表示所有后缀为.C的文件: 如果文件中用到 ...
- Java 堆内存模型
堆内存 Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象. 在 Java 中.堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old ).新生代 ...
- CMAKE 编译报错
报错如下: CMake Error: your C compiler: "CMAKE_C_COMPILER-NOTFOUND" was not found. 没有安装 gcc 和 ...