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

2023-11-27

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

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

productFlavors {
  create("global"){}
  create("local"){}
}

在上面的示例中,有 3 种不同的 buildType 和 2 种不同的 ProductFlavors。这意味着总共有 6 个 APK 变体。对于每个此 APK (全局发布、全局暂存、全局调试、本地发布、本地暂存、本地调试),例如我想使用不同的signingConfig。我该如何设置?

Tried:

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

Gradle 8.x 之后


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

Need to enable buildConfig for variant.buildConfigFields.set(),它是默认值was true但现在是false:

android {
    buildFeatures {
        buildConfig = true
    }
}

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

namespace is required现在在模块级构建脚本中。您需要指定它each module 分别地,并且应该是same as 包裹名字该模块的(不是 appId)。

这也和生成有关R类,它将成为my.module.package.R。另一个重大变化是你不能使用this.module.package.R用于参考资源(可绘制、字符串...)您依赖的另一个模块,您必须使用my.another.module.R.drawable.login。因为之前默认值android.nonTransitiveRClass标志是false and R包括您所依赖的每个模块的绘图。现在它的默认值是true, so R仅包含该模块的资源(improves构建时间)。

另外你需要删除package=""来自每个模块的 AndroidManifest.xml。

Gradle 7.x 之后


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

androidComponents {
    onVariants { variant ->
        variant.buildConfigFields.put("MY_CUSTOM_FIELD", BuildConfigField("String", "MyCustomValue", null))
        variant.manifestPlaceholders.put("MY_MANIFEST_FIELD", "MyManifestValue")
    }
}

在 AGP 7.0.x 上,有没有办法设置 signingConfig for mergedFlavor(构建类型+风格)。您可以单独设置 buildType 或flavor,但不能组合设置。

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

androidComponents {
    onVariants { variant ->
        variant.signingConfig?.setConfig(android.signingConfigs.getByName("buildTypeXFlavorA"))
    }
}

‎‎ ‎

Gradle 7.x 之前


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

1) 清单占位符

applicationVariants.all{
    val variant = this
}

没有 getter/settermanifestPlaceholders on variant目的。下列的this, 我们可以做variant.mergedFlavor可变的。环境manifestPlaceholders on variant.mergedFlavor做了工作。

import com.android.builder.core.DefaultProductFlavor

applicationVariants.all{
    val manifestPlaceholders: Map<String, String>
    val variant = this
    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.addManifestPlaceholders(manifestPlaceholders)
}

2)构建配置字段

使用相同的方法,调用addBuildConfigField(ClassFieldImpl(type, name, value)) on mutableMergedFlavor不工作。但instead,可以直接设置variant.

import com.android.builder.internal.ClassFieldImpl

applicationVariants.all{
    val buildConfigFields: List<ClassFieldImpl>
    val variant = this
    buildConfigFields.forEach { 
        variant.buildConfigField(it.type, it.name, it.value) 
    }
}

3) 签名配置 signingConfig可以设置为mutableMergedFlavor如上所示,除了debug变体。全部debug变体使用默认签名选项,即使您将其设置为打开variant.mergedFlavor。但如果你设置default如果为 null,那么您也可以覆盖它。

import com.android.builder.core.DefaultProductFlavor

signingConfigs {
    create("myDebug") {}
}
buildTypes {
    getByName("debug") {
        signingConfig = null // to override
    }
}
applicationVariants.all{
    val variant = this
    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.signingConfig = signingConfigs.getByName("myDebug")
}

将所有内容放在一起:

import com.android.build.gradle.api.ApplicationVariant
import com.android.builder.internal.ClassFieldImpl
import com.android.builder.model.SigningConfig
import com.android.builder.core.DefaultProductFlavor
import java.util.*

fun configureVariant(variant: ApplicationVariant,
                     signingConfig: SigningConfig,
                     buildConfigFields: List<ClassFieldImpl>,
                     manifestPlaceholders: Map<String, String>) {

    println("configureVariant: ${variant.name}")
    buildConfigFields.forEach {
        variant.buildConfigField(it.type, it.name, it.value)
    }

    val mutableMergedFlavor = variant.mergedFlavor as DefaultProductFlavor
    mutableMergedFlavor.signingConfig = signingConfig
    mutableMergedFlavor.addManifestPlaceholders(manifestPlaceholders)
}

android {
    signingConfigs {
        create("myDebug") {}
        create("myRelease") {}
    }

    flavorDimensions("region")
    productFlavors {
        create("global") {
            setDimension("region")
            setApplicationId("")
        }
        create("local") {
            setDimension("region")
            setApplicationId("")
        }
    }

    buildTypes {
        getByName("debug") {
            signingConfig = null
        }
    }

    applicationVariants.all {
        val variant = this
        when {
            variant.name.equals("localDebug", true) -> {
                configureVariant(
                        variant,
                        signingConfigs.getByName("localDebug"),
                        listOf(ClassFieldImpl("String", "NAME", "\"VALUE\"")),
                        mapOf("KEY" to "VALUE")
                )
            }
            variant.name.equals("globalStaging", true) -> {
                configureVariant(
                        variant,
                        signingConfigs.getByName("globalStaging"),
                        listOf(ClassFieldImpl("String", "NAME", "\"VALUE2\"")),
                        mapOf("KEY" to "VALUE2")
                )
            }
        }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐