基于应用程序变体的构建配置(BuildType + Flavor)

Jem*_*rov 9 android gradle kotlin gradle-kotlin-dsl

我正在尝试为应用程序变体设置signingConfig, manifestPlaceholders, 。buildConfigField我可以为每个构建类型设置它们或者!ProductFlavor 独立,但我需要的是根据 ProductFlavor和!构建类型。

buildTypes{
  getByName("debug"){}
  getByName("release"){}
  create("staging"){}
}

productFlavors {
  create("global"){}
  create("local"){}
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,有 3 种不同的 buildType 和 2 种不同的 ProductFlavors。这意味着总共有 6 个 APK 变体。对于每个APK(globalRelease、globalStaging、globalDebug、localRelease、localStaging、localDebug),我想使用不同的signingConfig。我该如何设置?

尝试过:

  • 如果我在buildType中设置它,那么将只有3个不同的signingConfigs
  • 如果我将其设置为风味,那么将只有 2 个不同的签名配置
  • 如果我尝试将其设置为applicationVariants.all{},则没有 setter 函数,只有 Variant 对象上的 getter (链接
  • 设置字段 on(variant.mergedFlavor as DefaultProductFlavor)不会将 buildConfigField 值添加到 BuildConfig.java (链接

Jem*_*rov 16

Gradle 8.x 之后

\n
\n
\n

错误:“构建类型包含自定义 BuildConfig 字段,但该功能已禁用”

\n
\n

需要启用buildConfigfor variant.buildConfigFields.set(),它的默认值 true但现在是false

\n
android {\n    buildFeatures {\n        buildConfig = true\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

错误:“无法创建 com.android.build.api.variant.impl.LibraryVariantBuilderImpl 类型的实例...\n未指定命名空间。在模块的构建\n文件中指定命名空间”

\n
\n

namespace现在在模块级构建脚本中是必需的。您需要为每个模块单独指定它,并且它应该与该模块的包名称相同 (而不是appId)。

\n

这也和生成的R类有关,它会变成my.module.package.R. 另一个重大更改是您不能用于this.module.package.R引用您所依赖的另一个模块的资源(可绘制、字符串...),您必须使用my.another.module.R.drawable.login. 因为以前标志的默认值android.nonTransitiveRClassfalse并且R包含您所依赖的每个模块的可绘制对象。现在它的默认值为true,因此R仅包含该模块的资源缩短构建时间)。

\n

此外,您需要package=""从每个模块的 AndroidManifest.xml 中删除。

\n

Gradle 7.x 之后

\n
\n

我们现在使用外部块applicationVariants.all{}来代替。此代码应该适用于 Gradle 7.0.2 和 AGP 7.0.1: androidComponents { onVariants{ .. }}android{}

\n
androidComponents {\n    onVariants { variant ->\n        variant.buildConfigFields.put("MY_CUSTOM_FIELD", BuildConfigField("String", "MyCustomValue", null))\n        variant.manifestPlaceholders.put("MY_MANIFEST_FIELD", "MyManifestValue")\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 AGP 7.0.x 上,无法设置 signingConfig( mergedFlavorbuildType+flavor)。您可以单独设置 buildType 或flavor,但不能组合设置。

\n

在 AGP 7.1.x 上,您可以做到。但它需要 AGP 7.1.0-alpha10、Gradle 7.2-rc-3、AndroidStudio BumbleBee 2021.1.1 alpha10:

\n
androidComponents {\n    onVariants { variant ->\n        variant.signingConfig?.setConfig(android.signingConfigs.getByName("buildTypeXFlavorA"))\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x8e\xe2\x80\x8e\n\xe2\x80\x8e

\n

Gradle 7.x 之前

\n
\n

要对不同变体(buildType+productFlavor)进行更改,我必须使用android.applicationVariants.all{}. 但是用不同的路径来实现多个signingConfig,,manifestPlaceholdersbuildConfigField

\n

1) 清单占位符

\n
androidComponents {\n    onVariants { variant ->\n        variant.buildConfigFields.put("MY_CUSTOM_FIELD", BuildConfigField("String", "MyCustomValue", null))\n        variant.manifestPlaceholders.put("MY_MANIFEST_FIELD", "MyManifestValue")\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

manifestPlaceholders对象没有 getter/setter variant。接下来我们可以使其variant.mergedFlavor可变。设置manifestPlaceholders确实variant.mergedFlavor有效。

\n
androidComponents {\n    onVariants { variant ->\n        variant.signingConfig?.setConfig(android.signingConfigs.getByName("buildTypeXFlavorA"))\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

2)构建配置字段

\n

用同样的方法,打电话addBuildConfigField(ClassFieldImpl(type, name, value))mutableMergedFlavor没有用。但相反,它可以直接设置在variant.

\n
applicationVariants.all{\n    val variant = this\n}\n
Run Code Online (Sandbox Code Playgroud)\n

3) 签名配置\nsigningConfig可以按上面所示进行设置mutableMergedFlavor,但变体除外debug。所有debug变体都使用默认签名选项,即使您将其设置为variant.mergedFlavor. 但如果您将默认值设置为 null,那么您也可以覆盖它。

\n
import com.android.builder.core.DefaultProductFlavor\n\napplicationVariants.all{\n    val manifestPlaceholders: Map<String, String>\n    val variant = this\n    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor\n    mutableMergedFlavor.addManifestPlaceholders(manifestPlaceholders)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

将所有内容放在一起:

\n
import com.android.builder.internal.ClassFieldImpl\n\napplicationVariants.all{\n    val buildConfigFields: List<ClassFieldImpl>\n    val variant = this\n    buildConfigFields.forEach { \n        variant.buildConfigField(it.type, it.name, it.value) \n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


归档时间:

查看次数:

3876 次

最近记录:

2 年,9 月 前