简体   繁体   English

Android - 根据构建类型更改风味版本名称

[英]Android - change flavor version name based on build type

I want to change version name for app flavors but only if it's a debug build.我想更改应用程序风格的版本名称,但前提是它是调试版本。

(eg debug builds will have versions like 1.0.1 D (DEBUG) 555 or 1.0.1 P (DEBUG) 555, however I want the release builds only to have version like 1.0.1) How can I achieve this? (例如,调试版本将具有 1.0.1 D (DEBUG) 555 或 1.0.1 P (DEBUG) 555 之类的版本,但是我希望发布版本仅具有 1.0.1 之类的版本)我该如何实现?

Basically I have these build types:基本上我有这些构建类型:

buildTypes {


    debug {
        versionNameSuffix " (DEBUG) " + mBuild

    }
    release {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), file('proguard-project.txt')
        signingConfig signingConfigs.release
    }
}

and these flavors (for different api environment):和这些口味(针对不同的 api 环境):

productFlavors {
    dev {
        versionName = android.defaultConfig.versionName + " D"
    }
    prod {
        versionName = android.defaultConfig.versionName + " P"
    }
}

Is there any way how to make release builds without product flavors version name change?有什么方法可以在不更改产品风味版本名称的情况下制作发布版本吗?

I've tried to set the version name dynamically via我试图通过动态设置版本名称

    buildTypes.each { buildType ->
    if(buildType.name == 'debug') {
        productFlavors.dev.versionName = android.defaultConfig.versionName + " D"
    }
}

but this results in但这导致

Could not find property 'dev' on GroupableProductFlavorDsl container.在 GroupableProductFlavorDsl 容器上找不到属性“dev”。

After hours of searching I've managed to remove all the changes made to the version name for the release build using this code经过数小时的搜索,我设法使用此代码删除了对发布版本的版本名称所做的所有更改

applicationVariants.all { variant ->
    if (variant.buildType.name == 'release') {
        variant.mergedFlavor.versionName = android.defaultConfig.versionName;
    }
}

For those wondering to use this using Kotlin DSL.对于那些想通过 Kotlin DSL 使用它的人。 At first try, it might not be allowing us to assign a new value to the version name.第一次尝试时,它可能不允许我们为版本名称分配新值。

在此处输入图片说明

The image above shown there's no setter for versionName for ProductFlavor class.上图显示了ProductFlavor类的versionName没有设置器。

Attempt 1 (cast to ProductFlavorImpl ):尝试 1(转换为ProductFlavorImpl ):

applicationVariants.forEach { variant ->
  if (variant.buildType.name != "release") {
    variant.mergedFlavor.let {
      it as ProductFlavorImpl
      it.versionName = "sampingan-${defaultConfig.versionName}"
    }
  }
}

it as ProductFlavorImpl still doesn't work, due to MergedFlavor cannot be cast ProductFlavorImpl and throw this error: it as ProductFlavorImpl仍然不起作用,因为MergedFlavor无法转换ProductFlavorImpl并抛出此错误:

com.android.builder.core.MergedFlavor cannot be cast to com.android.build.gradle.internal.api.dsl.model.ProductFlavorImpl

Attempt 2 (casting to MergedFlavor ) instead:尝试 2(转换为MergedFlavor ):

  //
  variant.mergedFlavor.let {
    it as com.android.builder.core.MergedFlavor
  }
  // 

After trial & error, it looks like we were unable to directly change the versionName with MergedFlavor , instead another error logs shown below:经过反复试验,看起来我们无法直接使用MergedFlavor更改versionName ,而是另一个错误日志如下所示:

versionName cannot be set on a mergedFlavor directly.
versionNameOverride can instead be set for variant outputs using the following syntax:
android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionNameOverride = "1.0.0"
        }
    }
}

Attempt 3 (using ApplicationVariant object) instead:尝试 3(使用ApplicationVariant对象):

So let's change our implementation to be like this所以让我们把我们的实现改成这样

    applicationVariants.all(object : Action<com.android.build.gradle.api.ApplicationVariant> {
        override fun execute(variant: com.android.build.gradle.api.ApplicationVariant) {
            println("variant: ${variant}")
            variant.outputs.all(object : Action<com.android.build.gradle.api.BaseVariantOutput> {
                override fun execute(output: com.android.build.gradle.api.BaseVariantOutput) {

                    if (variant.buildType.name != "release") {
                    (output as com.android.build.gradle.internal.api.ApkVariantOutputImpl)
                            .versionNameOverride = "prefix-${variant.versionName}"
                    }
                }
            })
        }
    })

This whole approach, inspired by @david-mihola answer.这整个方法的灵感来自@david-mihola 的回答。 He explained that groovy has its own magic here .他解释说, groovy在这里有它自己的魔力。

And if you want to change the APK name for each different buildTypes or productFlavors you can go to @david-mihola answer here .如果您想为每个不同的buildTypesproductFlavors更改APK 名称,您可以在此处访问 @david-mihola 答案。

Build Type should override the Product Flavor . Build Type应该覆盖Product Flavor Try next one.试试下一个。

buildTypes {

    release {
        versionName = android.defaultConfig.versionName
    }
}

The latest simple solution worked well and was tested.最新的简单解决方案运行良好并经过测试。 Define productflavour and buildTypes inside these and remove the versionName.在其中定义 productflavour 和 buildTypes 并删除 versionName。

And using output.versionNameOverride = versionName we can change versionName depending on buildType and productFlavour.使用output.versionNameOverride = versionName我们可以根据 buildType 和 productFlavour 更改 versionName。

Code:代码:

 applicationVariants.all { variant ->
    variant.outputs.all { output ->
        def flavor = variant.getFlavorName()
        def versionName = "1.0.0"
        switch (flavor){
            case "paid":
                flavor = "Paid"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.8"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.8"
                } else {
                    versionName = "1.0.0.8"
                }
                break
            case "free":
                flavor = "Free"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.14"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.14"
                } else {
                    versionName = "1.0.0.14"
                }
                break
            case "trial":
                flavor = "Trial"
                if (variant.buildType.name == 'release') {
                    versionName = "1.0.0.3"
                } else if (variant.buildType.name == 'staging') {
                    versionName = "1.0.0.3"
                } else {
                    versionName = "1.0.0.3"
                }
                break
        }
        output.versionNameOverride = versionName
        outputFileName = "${flavor}_v${versionName}.apk"
    }
}

I wanted to set a different versionName for debug build:我想为调试版本设置一个不同的versionName

android {
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            if (variant.buildType.name == 'debug') {
                output.versionNameOverride = "1"
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM