gradle 基于应用程序变体(BuildType + Flavor)构建脚本

ddhy6vgd  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在尝试设置signingConfigmanifestPlaceholdersbuildConfigField为应用程序变量。我可以为每个buildType**或!productFlavor独立,但我需要的是根据productFlavor和!**buildType。

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

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

在上面的例子中,有3个不同的buildType和2个不同的productFlavors。这意味着总共有6个APK变体。对于每个APK(*globalRelease,globalStaging,globalstage,localRelease,localStaging,localstage *),我想使用不同的signingConfig为例。我该怎么设置?
尝试:

  • 如果我在buildType中设置它,那么只有3个不同的signingConfigs
  • 如果我在flavor中设置它,那么将只有2个不同的signingConfigs
  • 如果我尝试在applicationVariants.all{}中设置它,没有setter函数,只有变量对象(link)上的getter函数。
  • (variant.mergedFlavor as DefaultProductFlavor)上设置字段不会将buildConfigField值添加到BuildConfig.java(link
8yparm6h

8yparm6h1#

Gradle 8.x之后

错误:“生成类型包含自定义BuildConfig字段,但该功能已禁用”
Need tovariant.buildConfigFields.set()启用buildConfig,它的默认值为wastrue,但现在是false

android {
    buildFeatures {
        buildConfig = true
    }
}

错误:“无法创建类型为com.android.build.API.variant.impl.LibraryVariantBuilderImpl的示例.未指定命名空间。在模块的构建文件中指定命名空间”
namespace现在是模块级构建脚本中的required。您需要为每个模块单独指定,并且必须与该模块的包名相同(而不是appId)。
这也与生成的R类有关,它将变成my.module.package.R。另一个突破性的变化是你不能使用this.module.package.R引用你所依赖的另一个模块的资源 (可绘制的,字符串...),你必须使用my.another.module.R.drawable.login。因为之前android.nonTransitiveRClass标志的默认值是false,而R包含了你所依赖的每个模块的可绘制对象。现在它的默认值是true,所以R只包含该模块的资源 *(improves构建时)。
此外,您需要从每个模块的AndroidManifest.xml中删除package=""

Gradle 7.x之后

而不是applicationVariants.all{}we now useandroidComponents { 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上,有mergedFlavoris no way to setsigningConfig(buildType+flavor)。您可以单独设置buildType或flavor,但不能组合设置。
在AGP 7.1.x上,你可以做到这一点。但它需要AGP 7.1.0-alpha 10,Gradle 7.2-rc-3,AndroidStudio BumbleBee 2021.1.1 alpha 10:

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

‎‎ ‎

Gradle 7.x之前

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

1)清单占位符

applicationVariants.all{
    val variant = this
}

variant对象上没有manifestPlaceholders的getter/setter。在this之后,我们可以使variant.mergedFlavor可变。在variant.mergedFlavor上设置manifestPlaceholders可以正常工作。

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)buildConfigField

使用相同的方法,在mutableMergedFlavor上调用addBuildConfigField(ClassFieldImpl(type, name, value))也不起作用。但是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)signingConfigsigningConfig可以在上面显示的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")
                )
            }
        }
    }
}

相关问题