为什么 Gradle 忽略发布{}并在调试版本上实施规则?
Why does Gradle disregard release{} and implement a rule on debug build as well?
我不确定这是否发生在以前,但我认为它发生在 Android Studio 及其 Gradle 最近更新之后。
也就是说,我正在尝试设置发布APK的输出路径。所以我做了这样的代码
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
def outputPathName = "./apk-release.apk"
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = file(outputPathName)
}
}
}
}
这会将 APK 从其默认位置 (/build/outputs/apk
) 移至 build.gradle
文件旁边。
但是,release{}
被忽略,Android Studio 将调试版本移动到此位置并重命名它。因此,无论我创建签名的 APK 还是按调试图标来测试调试版本,APK 都会被移动和重命名。它应该留在默认位置,对吧?
为什么会这样? Android Studio Gradle 中的错误或我的代码中的错误?
注意:我注意到在我为 APK 创建自定义名称的其他项目中也发生了同样的情况。它还将重命名调试 APK 并以相同的方式忽略 release{}
.
Android工作室版本:1.3。预览 5
the release{} is being disregarded
不是真的。 build.gradle
中的每一行 代码在处理脚本时执行。
Gradle 脚本不会在构建时执行代码。它们在那里定义构建过程的对象模型。在 Android Studio 中,Gradle 脚本不会在构建时读入和解释;它们会在项目打开时或您 "Sync Project with Gradle Files" 时读入。正是该对象模型填充了 Build Variants 视图之类的内容。
release
闭包并不是说 "this is only stuff that should be done on a release build"。它只是说 "hey, anything you can't recognize, like minifyEnabled
, see if that's a property or method or something on this here release
object"。您可以像这样编写 release
闭包的开始部分:
buildTypes {
release.minifyEnabled false
release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
release.signingConfig signingConfigs.config
}
甚至:
buildTypes.release.minifyEnabled false
buildTypes.release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildTypes.release.signingConfig signingConfigs.config
如果你愿意的话。
这就是为什么您通常会在 android {}
的末尾看到那种 applicationVariants
循环,因为(我认为)applicationVariants
是 Gradle 的一部分Android 插件 DSL,它将遍历所有应用程序变体。
因此,如果您只想影响 release
构建,请在循环中检查 variant
的构建类型:
def outputPathName = "./apk-release.apk"
applicationVariants.all { variant ->
def name = variant.buildType.name
if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
return; // Skip debug builds.
}
variant.outputs.each { output ->
output.outputFile = file(outputPathName)
}
}
(可能有更巧妙的过滤方法,但这是我一直在使用的...)
我不确定这是否发生在以前,但我认为它发生在 Android Studio 及其 Gradle 最近更新之后。
也就是说,我正在尝试设置发布APK的输出路径。所以我做了这样的代码
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
def outputPathName = "./apk-release.apk"
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = file(outputPathName)
}
}
}
}
这会将 APK 从其默认位置 (/build/outputs/apk
) 移至 build.gradle
文件旁边。
但是,release{}
被忽略,Android Studio 将调试版本移动到此位置并重命名它。因此,无论我创建签名的 APK 还是按调试图标来测试调试版本,APK 都会被移动和重命名。它应该留在默认位置,对吧?
为什么会这样? Android Studio Gradle 中的错误或我的代码中的错误?
注意:我注意到在我为 APK 创建自定义名称的其他项目中也发生了同样的情况。它还将重命名调试 APK 并以相同的方式忽略 release{}
.
Android工作室版本:1.3。预览 5
the release{} is being disregarded
不是真的。 build.gradle
中的每一行 代码在处理脚本时执行。
Gradle 脚本不会在构建时执行代码。它们在那里定义构建过程的对象模型。在 Android Studio 中,Gradle 脚本不会在构建时读入和解释;它们会在项目打开时或您 "Sync Project with Gradle Files" 时读入。正是该对象模型填充了 Build Variants 视图之类的内容。
release
闭包并不是说 "this is only stuff that should be done on a release build"。它只是说 "hey, anything you can't recognize, like minifyEnabled
, see if that's a property or method or something on this here release
object"。您可以像这样编写 release
闭包的开始部分:
buildTypes {
release.minifyEnabled false
release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
release.signingConfig signingConfigs.config
}
甚至:
buildTypes.release.minifyEnabled false
buildTypes.release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildTypes.release.signingConfig signingConfigs.config
如果你愿意的话。
这就是为什么您通常会在 android {}
的末尾看到那种 applicationVariants
循环,因为(我认为)applicationVariants
是 Gradle 的一部分Android 插件 DSL,它将遍历所有应用程序变体。
因此,如果您只想影响 release
构建,请在循环中检查 variant
的构建类型:
def outputPathName = "./apk-release.apk"
applicationVariants.all { variant ->
def name = variant.buildType.name
if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
return; // Skip debug builds.
}
variant.outputs.each { output ->
output.outputFile = file(outputPathName)
}
}
(可能有更巧妙的过滤方法,但这是我一直在使用的...)