动态versioncode,Android的摇篮:动态生成时更改VERSIONNAME

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

The interesting steps are:

Check uncommitted changes

Step version code and remove -SNAPSHOT

suffix from version name

Build

Step version name and add -SNAPSHOT

suffix for next development version

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

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.

My android plugin config:

defaultConfig {

versionCode versionCode as int // taken from gradle.properties

versionName versionName // taken from gradle.properties

minSdkVersion 10

targetSdkVersion 19

}

Things I tried:

preBuild << {

android.applicationVariants.each { variant ->

variant.versionName = versionName

}

}

But there's no versionName in a variant.

preBuild << {

android.buildTypes.each { type ->

type.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).

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.

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

解决方案

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

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.

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

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

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

}

}

}

}

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.

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

Manual execution (from comments)

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

Check uncommitted 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!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值