如何在Android Gradle中自动增加versionCode

我正在尝试基于Gradle的新的Android构build系统,我在想,使用它自动增加versionCode的最佳方法是什么? 我正在考虑两个选项

  1. 创buildversionCode文件,从中读取数字,增加它并将其写回到文件中
  2. parsingAndroidManifest.xml,从中读取versionCode,增加它并将其写回到AndroidManifest.xml

有没有更简单或合适的解决scheme?

有没有人使用mentiod选项之一,可以与我分享?

我已经决定第二个选项 – parsingAndroidManifest.xml 。 这是工作片段。

 task('increaseVersionCode') << { def manifestFile = file("AndroidManifest.xml") def pattern = Pattern.compile("versionCode=\"(\\d+)\"") def manifestText = manifestFile.getText() def matcher = pattern.matcher(manifestText) matcher.find() def versionCode = Integer.parseInt(matcher.group(1)) def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"") manifestFile.write(manifestContent) } tasks.whenTaskAdded { task -> if (task.name == 'generateReleaseBuildConfig') { task.dependsOn 'increaseVersionCode' } } 

在这种情况下, versionCode被发布用于发布版本。 为了增加debugging版本,在task.whenTaskAddedcallback中改变task.name方程。

我使用这个代码来更新versionCode和versionName,使用“major.minor.patch.build”scheme。

 import java.util.regex.Pattern task('increaseVersionCode') << { def manifestFile = file("src/main/AndroidManifest.xml") def pattern = Pattern.compile("versionCode=\"(\\d+)\"") def manifestText = manifestFile.getText() def matcher = pattern.matcher(manifestText) matcher.find() def versionCode = Integer.parseInt(matcher.group(1)) def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"") manifestFile.write(manifestContent) } task('incrementVersionName') << { def manifestFile = file("src/main/AndroidManifest.xml") def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"") def manifestText = manifestFile.getText() def matcherVersionNumber = patternVersionNumber.matcher(manifestText) matcherVersionNumber.find() def majorVersion = Integer.parseInt(matcherVersionNumber.group(1)) def minorVersion = Integer.parseInt(matcherVersionNumber.group(2)) def pointVersion = Integer.parseInt(matcherVersionNumber.group(3)) def buildVersion = Integer.parseInt(matcherVersionNumber.group(4)) def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1) def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"") manifestFile.write(manifestContent) } tasks.whenTaskAdded { task -> if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') { task.dependsOn 'increaseVersionCode' task.dependsOn 'incrementVersionName' } } 

它似乎并不是你正在使用的确切的设置,但在我的情况下,构build正在由jenkins运行,我想使用它的$ BUILD_NUMBER作为应用程序的versionCode。 下面在那里为我做了诡计。

 defaultConfig { ... versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999 ... } 

我正在使用版本代码的时间戳:

 def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger() defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code } 

如果您在build.gradle文件中保存版本代码,请使用下面的代码片段:

 import java.util.regex.Pattern task('increaseVersionCode') << { def buildFile = file("build.gradle") def pattern = Pattern.compile("versionCode\\s+(\\d+)") def manifestText = buildFile.getText() def matcher = pattern.matcher(manifestText) matcher.find() def versionCode = Integer.parseInt(matcher.group(1)) def manifestContent = matcher.replaceAll("versionCode " + ++versionCode) buildFile.write(manifestContent) } 

要考虑产品风格和构buildtypes,并使用@ sealskej的逻辑来parsing清单:

 android.applicationVariants.all { variant -> /* Generate task to increment version code for release */ if (variant.name.contains("Release")) { def incrementVersionCodeTaskName = "increment${variant.name}VersionCode" task(incrementVersionCodeTaskName) << { if (android.defaultConfig.versionCode == -1) { def manifestFile = file(android.sourceSets.main.manifest.srcFile) def pattern = Pattern.compile("versionCode=\"(\\d+)\"") def manifestText = manifestFile.getText() def matcher = pattern.matcher(manifestText) matcher.find() def versionCode = Integer.parseInt(matcher.group(1)) android.defaultConfig.versionCode = versionCode + 1 def manifestContent = matcher.replaceAll("versionCode=\"" + android.defaultConfig.versionCode + "\"") manifestFile.write(manifestContent) } } def hookTask = variant.generateBuildConfig hookTask.dependsOn(incrementVersionCodeTaskName) } } 

Gradle高级构build版本是Android的一个插件,可以自动生成versionCodeversionName 。 有很多的定制。 在这里你可以find更多关于它的信息https://github.com/moallemi/gradle-advanced-build-version

递增VersionCode任务(整数):

这可以通过将版本码增加1 ,例如:

  android:versionCode="1" 
 1 + 1 = 2 
 import java.util.regex.Pattern task incrementVersionCode << { def manifestFile = file('AndroidManifest.xml') def matcher = Pattern.compile('versionCode=\"(\\d+)\"') .matcher(manifestFile.getText()) matcher.find() def manifestContent = matcher.replaceAll('versionCode=\"' + ++Integer.parseInt(matcher.group(1)) + '\"') manifestFile.write(manifestContent) } 

递增VersionName任务(string):

警告:必须包含1expression式

这可以通过将版本名称递增0.01 ,例如:您可以轻松修改和更改您的增量或添加更多数字。

 android:versionName="1.0" 
 1.00 + 0.01 -> 1.01 1.01 + 0.01 -> 1.02 1.10 + 0.01 -> 1.11 1.99 + 0.01 -> 2.0 1.90 + 0.01 -> 1.91 
 import java.util.regex.Pattern task incrementVersionName << { def manifestFile = file('AndroidManifest.xml') def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\"') .matcher(manifestFile.getText()) matcher.find() def versionName = String.format("%.2f", Integer .parseInt(matcher.group(1)) + Double.parseDouble("." + matcher .group(2)) + 0.01) def manifestContent = matcher.replaceAll('versionName=\"' + versionName + '\"') manifestFile.write(manifestContent) } 

之前:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exmaple.test" android:installLocation="auto" android:versionCode="1" android:versionName="1.0" > 

后:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exmaple.test" android:installLocation="auto" android:versionCode="2" android:versionName="1.01" > 

要添加到@ sealskej的文章,这是如何更新您的版本代码和版本名称(在这里我假设你的主要和次要版本都是0):

 task('increaseVersion') << { def manifestFile = file("AndroidManifest.xml") def patternVersionCode = Pattern.compile("versionCode=\"(\\d+)\"") def manifestText = manifestFile.getText() def matcherVersionCode = patternVersionCode.matcher(manifestText) matcherVersionCode.find() def versionCode = Integer.parseInt(matcherVersionCode.group(1)) def manifestContent = matcherVersionCode.replaceAll("versionCode=\"" + ++versionCode + "\"") manifestFile.write(manifestContent) def patternVersionNumber = Pattern.compile("versionName=\"0.0.(\\d+)\"") manifestText = manifestFile.getText() def matcherVersionNumber = patternVersionNumber.matcher(manifestText) matcherVersionNumber.find() def versionNumber = Integer.parseInt(matcherVersionNumber.group(1)) manifestContent = matcherVersionNumber.replaceAll("versionName=\"0.0." + ++versionNumber + "\"") manifestFile.write(manifestContent) } 

那这个呢 ? 添加到build.gradle(应用程序模块)

 def getBuildVersionCode() { def date = new Date() def formattedDate = date.format('yyyyMMdd') def formattedSeconds = date.format('HHmmssSSS') def formatInt = formattedDate as int; def SecondsInt = formattedSeconds as int; return (formatInt + SecondsInt) as int } defaultConfig { applicationId "com.app" minSdkVersion 17 targetSdkVersion 22 versionCode getBuildVersionCode() versionName "1.0" } 

如果你在gradle.build文件(目前大多数情况下)写你的versionCode ,这是一个解决方法。 有点愚蠢(更新“自我”),但它的作品!

 import java.util.regex.Pattern task('increaseVersionCode') << { def buildFile = file("build.gradle") def pattern = Pattern.compile("versionCode(\\s+\\d+)") def buildText = buildFile.getText() def matcher = pattern.matcher(buildText) matcher.find() def versionCode = android.defaultConfig.versionCode def buildContent = matcher.replaceAll("versionCode " + ++versionCode) buildFile.write(buildContent) System.out.println("Incrementing Version Code ===> " + versionCode) } tasks.whenTaskAdded { task -> if (task.name == 'generateReleaseBuildConfig') { task.dependsOn 'increaseVersionCode' } } 

所以当我正在研究大部分的解决scheme时,他们很好,但还不够,所以我写了这个,每个多部署一个增量:

这将在编译debugging版本时递增构build,并在部署时增加点和版本代码。

 import java.util.regex.Pattern def incrementVersionName(int length, int index) { def gradleFile = file("build.gradle") def versionNamePattern = Pattern.compile("versionName\\s*\"(.*?)\"") def gradleText = gradleFile.getText() def matcher = versionNamePattern.matcher(gradleText) matcher.find() def originalVersion = matcher.group(1) def originalVersionArray = originalVersion.split("\\.") def versionKeys = [0, 0, 0, 0] for (int i = 0; i < originalVersionArray.length; i++) { versionKeys[i] = Integer.parseInt(originalVersionArray[i]) } def finalVersion = "" versionKeys[index]++; for (int i = 0; i < length; i++) { finalVersion += "" + versionKeys[i] if (i < length - 1) finalVersion += "." } System.out.println("Incrementing Version Name: " + originalVersion + " ==> " + finalVersion) def newGradleContent = gradleText.replaceAll("versionName\\s*\"(.*?)\"", "versionName \"" + finalVersion + "\"") gradleFile.write(newGradleContent) } def incrementVersionCode() { def gradleFile = file("build.gradle") def versionCodePattern = Pattern.compile("versionCode\\s*(\\d+)") def gradleText = gradleFile.getText() def matcher = versionCodePattern.matcher(gradleText) matcher.find() def originalVersionCode = Integer.parseInt(matcher.group(1) + "") def finalVersionCode = originalVersionCode + 1; System.out.println("Incrementing Version Code: " + originalVersionCode + " ==> " + finalVersionCode) def newGradleContent = gradleText.replaceAll("versionCode\\s*(\\d+)", "versionCode " + finalVersionCode) gradleFile.write(newGradleContent) } task('incrementVersionNameBuild') << { incrementVersionName(4, 3) } task('incrementVersionNamePoint') << { incrementVersionName(3, 2) } task('incrementVersionCode') << { incrementVersionCode() } def incrementedBuild = false def incrementedRelease = false tasks.whenTaskAdded { task -> System.out.println("incrementedRelease: " + incrementedRelease) System.out.println("incrementedBuild: " + incrementedBuild) System.out.println("task.name: " + task.name) if (!incrementedBuild && task.name.matches('generate.*?DebugBuildConfig')) { task.dependsOn 'incrementVersionNameBuild' incrementedBuild = true return } if (!incrementedRelease && task.name.matches('generate.*?ReleaseBuildConfig')) { task.dependsOn 'incrementVersionCode' task.dependsOn 'incrementVersionNamePoint' incrementedRelease = true return } } 

我的方法是从构build文件夹读取清单文件,并从那里得到buildVersion,比我删除一个文件夹。 当任务创build新清单时,我递增的buildVersionvariables已经存在。

 def versionPattern = "Implementation-Version=(\\d+.\\d+.\\d+.\\d+\\w+)" task generateVersion (dependsOn : 'start') { // read build version from previous manifest def file = file("build/libs/MANIFEST.MF") if (file.exists()) { def pattern = Pattern.compile(versionPattern) def text = file.getText() def matcher = pattern.matcher(text) matcher.find() buildNumber = Integer.parseInt(matcher.group(1)) // increment build version version = "${majorVer}.${minorVer}.${patchVer}.${++buildNumber}${classifier}_${access}" } else version = "${majorVer}.${minorVer}.${patchVer}.1${classifier}_${access}" } task specifyOutputDir (dependsOn : 'generateVersion', type : JavaCompile) { // create a folder for new build destinationDir = file("build/${version}/") } task clean (dependsOn : 'generateVersion', type : Delete) { doLast { delete "build/${version}" println 'Build directory is deleted' } } task configureJar (dependsOn : 'generateVersion', type : Jar) { baseName = applicationName version = project.version archiveName = "${applicationName}_ver${version}.${extension}" manifest {[ "Main-Class" : mainClassName, "Implementation-Title" : name, "Implementation-Version" : version, "Access" : access, "Developer" : developer ]} }