Android Gradle:在构建时动态更改 versionName [英] Android Gradle: Dynamically change versionName at build time

查看:21
本文介绍了Android Gradle:在构建时动态更改 versionName的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用自定义版本的 gradle-release 插件在 Android 中模拟 Maven 发布插件:https://github.com/townsfolk/gradle-release

I'm trying to emulate Maven release plugin in Android by using a customized version of gradle-release plugin: https://github.com/townsfolk/gradle-release

有趣的步骤是:

  • 检查未提交的更改
  • 步骤版本代码并删除 -SNAPSHOT来自版本名称的后缀
  • 构建
  • 步骤版本名称并添加-SNAPSHOT下一个开发版本的后缀

但是生成的 APK 始终具有以前的版本(即 1.0.0-SNAPSHOT 而不是 1.0.0).

However the generated APK always has the previous versions (i.e. 1.0.0-SNAPSHOT instead of 1.0.0).

版本号存储在 gradle.properties 中并正确更新,因此我假设我还需要更新数据模型中的版本以使更改生效.

Version numbers are stored and correctly updated in gradle.properties, so I'm assuming that I need to update the versions in the data model as well for the changes to take effect.

我的安卓插件配置:

defaultConfig {
    versionCode versionCode as int  // taken from gradle.properties
    versionName versionName // taken from gradle.properties
    minSdkVersion 10
    targetSdkVersion 19
}

我尝试过的事情:

preBuild << {
    android.applicationVariants.each { variant ->
        variant.versionName = versionName
    }
}

但是在变体中没有 versionName.

But there's no versionName in a variant.

preBuild << {
    android.buildTypes.each { type ->
        type.versionName = versionName
    }
}

但是类型中没有 versionName.

But there's no versionName in a type.

preBuild << {
    android.productFlavors.each { flavor ->
        flavor.versionName = versionName
    }
}

但我的应用中没有任何风格(仅限普通调试和发布构建类型).

But there are no flavors in my app (plain debug and release build types only).

我的替代方法是在调用 Gradle 之前编写一个 bash/bat 脚本来步进版本,这几乎违背了使用 Groovy 改进构建定制的目的.

My alternative is to write a bash/bat script to step the versions before invoking Gradle, which pretty much defeats the purpose of using Groovy to improve build customization.

如何在执行阶段在 Android Gradle 插件中动态更新版本?

How can I update versions dynamically in the Android Gradle plugin in the execution phase?

推荐答案

这就是 buildTypes 的用途.你所描述的是一个 release 构建,IMO.

That's what buildTypes are for. What you're describing is a release build, IMO.

这是一个例子:当执行 assembleDebug 时,它会给你一个快照构建,执行 assembleRelease 会给你一个干净的构建,没有任何后缀和递增的版本号.下一个调试版本也将使用递增的数字.

Here's an example: when executing assembleDebug it will give you a snapshot build, and executing assembleRelease will give you a clean build without any suffix and incremented version number. The next debug build will also use the incremented number.

以下是在文件夹中创建文件时的全功能构建.它也应该适用于口味,但这只是一个副产品:).Gradle 2.2.1,Android 插件 1.1.3

The following is a fully functional build when the files are created in a folder. It should also work with flavors, but that's just a side product :). Gradle 2.2.1, Android plugin 1.1.3

apply plugin: 'com.android.application'
apply from: 'auto-version.gradle'

buildscript {
    repositories { jcenter() }
    dependencies { classpath 'com.android.tools.build:gradle:1.1.3' }
}

android {
    buildToolsVersion = "21.1.2"
    compileSdkVersion = "android-21"

    buildTypes {
        debug {
            versionNameSuffix "-SNAPSHOT"
        }
    }
}

println "config code: ${calculateVersionCode()}, name: ${calculateVersionName()}"

src/main/AndroidManifest.xml

<manifest package="com.example" />

auto-version.gradle

ext {
    versionFile = new File(project.rootDir, 'version.properties')
    calculateVersionName = {
        def version = readVersion()
        return "${version['major']}.${version['minor']}.${version['build']}"
    }
    calculateVersionCode = {
        def version = readVersion()
        def major = version['major'] as int // 1..∞
        def minor = version['minor'] as int // 0..99
        def build = version['build'] as int // 0..999
        return (major * 100 + minor) * 1000 + build
    }
}


Properties readVersion() {
    def version = new Properties()
    def stream
    try {
        stream = new FileInputStream(versionFile)
        version.load(stream)
    } catch (FileNotFoundException ignore) {
    } finally {
        if (stream != null) stream.close()
    }
    // safety defaults in case file is missing
    if(!version['major']) version['major'] = "1"
    if(!version['minor']) version['minor'] = "0"
    if(!version['build']) version['build'] = "0"
    return version
}

void incrementVersionNumber() {
    def version = readVersion()

    // careful with the types, culprits: "9"++ = ":", "9" + 1 = "91"
    def build = version['build'] as int
    build++
    version['build'] = build.toString()

    def stream = new FileOutputStream(versionFile)
    try {
        version.store(stream, null)
    } finally {
        stream.close()
    }
}

task incrementVersion {
    description "Increments build counter in ${versionFile}"
    doFirst {
        incrementVersionNumber()
    }
}

if (plugins.hasPlugin('android') || plugins.hasPlugin('android-library')) {
    android {
        defaultConfig {
            versionName = calculateVersionName()
            versionCode = calculateVersionCode()
        }

        afterEvaluate {
            def autoIncrementVariant = { variant ->
                if (variant.buildType.name == buildTypes.release.name) { // don't increment on debug builds
                    variant.preBuild.dependsOn incrementVersion
                    incrementVersion.doLast {
                        variant.mergedFlavor.versionName = calculateVersionName()
                        variant.mergedFlavor.versionCode = calculateVersionCode()
                    }
                }
            }
            if (plugins.hasPlugin('android')) {
                applicationVariants.all { variant -> autoIncrementVariant(variant) }
            }
            if (plugins.hasPlugin('android-library')) {
                libraryVariants.all { variant -> autoIncrementVariant(variant) }
            }
        }
    }
}

执行gradle assembleDebug正常构建,gradle assembleRelease递增和构建,gradle incrementVersion只是递增.注意:gradle assemble要小心,因为assembleDebugassembleRelease的顺序会产生不同的结果.

Execute gradle assembleDebug to build normally, gradle assembleRelease to increment and build, and gradle incrementVersion to just increment. Note: be careful with gradle assemble because the order of assembleDebug and assembleRelease will yield different results.

检查 build 目录中生成的文件,看看这些值是否符合您的喜好.

Check the generated files in the build directory to see if the values are to your liking.

您可能有多种风格,在这种情况下,版本会多次递增,因为多个变体与发布构建类型相匹配.最初的问题是没有味道.如果您想在版本号递增时获得更多控制,只需删除 afterEvaluate 块并随时调用 incrementVersion 任务:

It is possible you have multiple flavors in which case the version is incremented multiple times because multiple variants match the release build type. The original quesion was for no flavors. If you want to have more control when the version number is incremented just remove the afterEvaluate block and call the incrementVersion task whenever you want:

gradle incrementVersion assembleFreeRelease assemblePaidRelease

(上面的手动执行是一个未经测试的想法.)

(The above manual execution is an untested idea.)

检查未提交的更改"未包含在此答案中,这是另一个游戏.如果我理解正确,您可以连接到 tasks.preBuild.doFirst {/*fail here if uncommited changes*/}.但这在很大程度上取决于您的版本控制.再问一个问题,了解更多!

The "Check uncommitted changes" are not covered in this answer, that's another game. You could hook on to tasks.preBuild.doFirst { /*fail here if uncommited changes*/ } if I understand correctly. But that highly depends on your version control. Ask another question for more!

这篇关于Android Gradle:在构建时动态更改 versionName的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆