Android、Gradle、产品口味和清单
Android, Gradle, product flavors and the manifest
在 build.gradle
中,我设置了产品口味:
productFlavors
{
AlternateFlavour
{
applicationId "com.myapp.alternateflavour"
}
}
然后在 sourceSets 部分,我为这些风格使用不同的资源、资产和清单目录:
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
AlternateFlavour {
manifest.srcFile 'manifest-tmp/AlternateFlavour/AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res-tmp/AlternateFlavour']
assets.srcDirs = ['assets-tmp/AlternateFlavour']
}
}
到目前为止没问题。
在部分自动生成的风味所使用的清单中,我有:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.myapp"
android:versionCode="1010001"
android:versionName="V1.1.0.1" >
但在根项目中的原始清单如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.myapp"
android:versionCode="1010000"
android:versionName="V1.1.0.DEBUG" >
这会导致 Gradle 失败:
Error:
Attribute manifest@versionCode value=(1010001) from AndroidManifest.xml:4:5-28
is also present at AndroidManifest.xml:4:5-28 value=(1010000).
Attributes of <manifest> elements are not merged.
为什么它试图与原始清单合并,当我指定它应该查看其他地方时?
我该如何阻止它?
我预计有些人会质疑我为什么要这样做,或者为什么我不使用建议的风味项目结构。好吧,我需要一个正常的清单以在 Gradle 之外使用,例如用于从 Eclipse 部署(请一次做一件事!)我还需要通过构建过程注入版本。
Why is it trying to merge with the original manifest at all, when I've specified it should look elsewhere?
你说 flavor 清单在别处。清单合并过程合并所有相关清单:
main
- 构建类型
- 产品口味
- 图书馆
main
中的清单始终是相关的。
And how can I stop this?
你不需要,因为 main
中的清单总是相关的。
通常,最好的解决方案是从 所有 清单中删除 versionCode
和 versionName
,并将它们设置在 build.gradle
,您可以在其中进行完全的编程控制。
下一个最佳解决方案是将 versionCode
和 versionName
从 main
清单移到您未在此处显示的产品风味中。我从来没有见过有人只创造一种产品风味,据我所知这是毫无意义的——你只能创造一种产品风味(因为据我所知,一旦你引入风味就没有无味的构建)。产品口味通常以 2+ 为一组出现(例如,使用 Play 服务的 google
口味和不使用 Play 服务的 standalone
口味)。如果 main
中的值真的适合非 AlternateFlavour
风格,请将你的 main
version...
内容移到那里。
除此之外,欢迎您查看 the documentation on the manifest merger process 看看您是否可以输入正确的指令来获得您想要的。
我会牢记@CommonsWare 在他们的回答中所说的话,但现在,我已经解决了这个问题:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.myapp.myapp"
tools:replace="android:versionName,android:versionCode"
android:versionCode="1010001"
android:versionName="V1.1.0.1" >
注意两个 tools
片段。
我最初知道这个,但我推迟了尝试,因为完整的 Gradle 错误涉及三个问题:
- 版本代码
- 版本名称
- 地图 API 键
所有这些都是自动插入的。但是,它只提供了 tools:replace
作为最后一个建议,所以我的印象是它不适用于 manifest
属性。事实上它确实如此。
Android官方文档会告诉你为什么多个清单文件会在构建过程中合并。
我遇到了同样的问题,但我想用不同的版本代码获得不同的风格,versionName.When 你想这样做,从 AndroidManifest.xml 中删除所有版本代码和版本名称,然后尝试在 build.gradle
文件中添加口味。
在 build.gradle
中,我设置了产品口味:
productFlavors
{
AlternateFlavour
{
applicationId "com.myapp.alternateflavour"
}
}
然后在 sourceSets 部分,我为这些风格使用不同的资源、资产和清单目录:
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
AlternateFlavour {
manifest.srcFile 'manifest-tmp/AlternateFlavour/AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res-tmp/AlternateFlavour']
assets.srcDirs = ['assets-tmp/AlternateFlavour']
}
}
到目前为止没问题。
在部分自动生成的风味所使用的清单中,我有:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.myapp"
android:versionCode="1010001"
android:versionName="V1.1.0.1" >
但在根项目中的原始清单如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.myapp"
android:versionCode="1010000"
android:versionName="V1.1.0.DEBUG" >
这会导致 Gradle 失败:
Error:
Attribute manifest@versionCode value=(1010001) from AndroidManifest.xml:4:5-28
is also present at AndroidManifest.xml:4:5-28 value=(1010000).
Attributes of <manifest> elements are not merged.
为什么它试图与原始清单合并,当我指定它应该查看其他地方时?
我该如何阻止它?
我预计有些人会质疑我为什么要这样做,或者为什么我不使用建议的风味项目结构。好吧,我需要一个正常的清单以在 Gradle 之外使用,例如用于从 Eclipse 部署(请一次做一件事!)我还需要通过构建过程注入版本。
Why is it trying to merge with the original manifest at all, when I've specified it should look elsewhere?
你说 flavor 清单在别处。清单合并过程合并所有相关清单:
main
- 构建类型
- 产品口味
- 图书馆
main
中的清单始终是相关的。
And how can I stop this?
你不需要,因为 main
中的清单总是相关的。
通常,最好的解决方案是从 所有 清单中删除 versionCode
和 versionName
,并将它们设置在 build.gradle
,您可以在其中进行完全的编程控制。
下一个最佳解决方案是将 versionCode
和 versionName
从 main
清单移到您未在此处显示的产品风味中。我从来没有见过有人只创造一种产品风味,据我所知这是毫无意义的——你只能创造一种产品风味(因为据我所知,一旦你引入风味就没有无味的构建)。产品口味通常以 2+ 为一组出现(例如,使用 Play 服务的 google
口味和不使用 Play 服务的 standalone
口味)。如果 main
中的值真的适合非 AlternateFlavour
风格,请将你的 main
version...
内容移到那里。
除此之外,欢迎您查看 the documentation on the manifest merger process 看看您是否可以输入正确的指令来获得您想要的。
我会牢记@CommonsWare 在他们的回答中所说的话,但现在,我已经解决了这个问题:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.myapp.myapp"
tools:replace="android:versionName,android:versionCode"
android:versionCode="1010001"
android:versionName="V1.1.0.1" >
注意两个 tools
片段。
我最初知道这个,但我推迟了尝试,因为完整的 Gradle 错误涉及三个问题:
- 版本代码
- 版本名称
- 地图 API 键
所有这些都是自动插入的。但是,它只提供了 tools:replace
作为最后一个建议,所以我的印象是它不适用于 manifest
属性。事实上它确实如此。
Android官方文档会告诉你为什么多个清单文件会在构建过程中合并。
我遇到了同样的问题,但我想用不同的版本代码获得不同的风格,versionName.When 你想这样做,从 AndroidManifest.xml 中删除所有版本代码和版本名称,然后尝试在 build.gradle
文件中添加口味。