Android Gradle:在构build时dynamic更改versionName

我试图通过使用gradle-release插件的定制版本来模拟Android中的Maven发布插件: https : //github.com/townsfolk/gradle-release

有趣的步骤是:

  • 检查未提交的更改
  • 步骤版本代码并从版本名称中删除-SNAPSHOT后缀
  • build立
  • Step版本名称并为下一个开发版本添加-SNAPSHOT后缀

然而,生成的APK总是有以前的版本(即1.0.0-SNAPSHOT而不是1.0.0)。

版本号在gradle.properties中存储并正确更新,所以我假设我需要更新数据模型中的版本以及更改才能生效。

我的android插件configuration:

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。

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

但是在types中没有versionName。

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

但是在我的应用程序中没有任何风格(只有普通的debugging和发布版本types)。

我的另一种方法是在调用Gradle之前编写一个bash / bat脚本来执行这个版本,这几乎违背了使用Groovy来改进构build自定义的目的。

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

Solutions Collecting From Web of "Android Gradle:在构build时dynamic更改versionName"

这是buildTypes的用途。 你所描述的是一个release版本,国际海事组织。

下面是一个例子:当执行assembleDebug它会给你一个快照构build,执行assembleRelease会给你一个干净的构build,没有任何后缀和增加版本号。 下一个debugging版本也将使用递增的数字。

以下是在文件夹中创build文件时的完整function版本。 它也应该与口味,但这只是一个副产品:)。 Gradle 2.2.1,Android插件1.1.3

的build.gradle

 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 /主/ AndroidManifest.xml中

 <manifest package="com.example" /> 

自动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正常构build, gradle assembleRelease增量构build, gradle incrementVersion增量。 注意:请小心使用gradle assemble因为assembleDebugassembleRelease的顺序会产生不同的结果。

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

手动执行(来自评论)

可能有多种风格,在这种情况下,版本会多次增加,因为多个变体与发布构buildtypes相匹配。 原来的问题是没有味道。 如果您希望在版本号增加时拥有更多的控制权,则只要删除afterEvaluate块并afterEvaluate调用incrementVersion任务即可:

 gradle incrementVersion assembleFreeRelease assemblePaidRelease 

(上面的手动执行是一个未经testing的想法。)

检查未提交的更改

这个答案不包括“检查未提交的变更”,这是另一个游戏。 你可以连接到tasks.preBuild.doFirst { /*fail here if uncommited changes*/ }如果我理解正确的tasks.preBuild.doFirst { /*fail here if uncommited changes*/ }就会tasks.preBuild.doFirst { /*fail here if uncommited changes*/ } 。 但是这很大程度上取决于你的版本控制。 问另一个问题了解更多!

这并不直接解决如何完全更改versionName的问题,但这是我用来为我的buildTypes附加一个后缀的问题:

 defaultConfig { versionName "1.0" } buildTypes { debug { versionNameSuffix "-SNAPSHOT" } } 

我需要将当前git commit代码版本号附加到版本名称。 它在许多情况下真正的方便。 我结束了简单的gradle文件

 apply plugin: 'com.android.application' android { compileSdkVersion 21 buildToolsVersion "21.1.2" def gitCommitCount = "git rev-list HEAD --count".execute().text.trim() defaultConfig { applicationId "my.app.package.name" minSdkVersion 16 targetSdkVersion 21 versionCode 6 versionName "0.8" } buildTypes { debug { versionNameSuffix ".${gitCommitCount}" } release { versionNameSuffix ".${gitCommitCount}" minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } 

类似于gitCommitCount,您可以生成自己的variables来自定义版本名称。 因为我只是执行一个terminal命令将其结果存储在一个variables。

我只是使用了Javanator的答案并对其进行了一些修改,以便提交计数不仅有助于更改名称,而且还确保版本代码也保持唯一。 下面是我所做的一个例子(也许几件事情可以优化,但是为我做的工作):

 android { compileSdkVersion 25 buildToolsVersion "25.0.2" def gitCommitCount = "git rev-list HEAD --count".execute().text.trim().toBigInteger() project.ext.set("versionCode", gitCommitCount) project.ext.set("versionNameSuffix", "(${gitCommitCount})") defaultConfig { applicationId "my.app.package.name" minSdkVersion 15 targetSdkVersion 25 versionCode project.versionCode versionName "1.0" versionNameSuffix project.versionNameSuffix setProperty("archivesBaseName", "MyProject-$versionName") .... } signingConfigs { config { ......... } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.config } } packagingOptions { ..... } applicationVariants.all { variant -> variant.outputs.each { output -> output.outputFile = new File( output.outputFile.parent, output.outputFile.name.replace(".apk", "-${variant.versionName}.apk")) } } } 

我面临着类似的需求,即为发布版和非发布版构build单独的构build逻辑。 除了不同的版本,我不得不使用一组不同的依赖关系,甚至不同的存储库。

没有一个可用的插件具有我需要的所有function,所以我开发了自己的解决scheme,基于简单的方法 – 命令行参数。

调用gradle构build脚本时,可以传递一个命令行参数,如下所示:

  gradle生成-PmyParameter = myValue 

或在我的情况

  gradle build -PisRelease = true 

Gradle将parsing它,它将自动作为项目对象的属性。 你可以像这样使用它:

 if (project.isRelease) { // Here be the logic! } 

我将这个逻辑提取到一个单独的插件中,并且我已经成功地在不同的项目中使用它。

虽然这不能直接回答你的问题,但我希望给你另一个angular度来思考这个问题和另一个可能的解决scheme。