如何使用Gradle脚本自动增加和释放在Android Studio中签名的apk

我试图自动更新Android Manifest中的versionName和VersionCode参数,并在输出文件名中使用它们而不是“app-release.apk”。

从这个站点我添加这个代码在我的build.gradle文件中:

import java.util.regex.Pattern import com.android.builder.core.DefaultManifestParser def mVersionCode def mNextVersionName def newName 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() mVersionCode = Integer.parseInt(matcher.group(1)) def manifestContent = matcher.replaceAll("versionCode=\"" + ++mVersionCode + "\"") 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)) mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1) def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"") manifestFile.write(manifestContent) } tasks.whenTaskAdded { task -> if (task.name == 'generateReleaseBuildConfig') { task.dependsOn 'increaseVersionCode' task.dependsOn 'incrementVersionName' } } 

这个代码完美地工作,2个任务运行并正确地更新清单文件。 现在我想在这个mNextVersionNamerelease块中使用2个variablesmVersionCodemNextVersionName

 newName = defaultConfig.applicationId + "-" + mNextVersionName + " (" + mVersionCode + ").apk" applicationVariants.all { variant -> variant.outputs.each {output -> def file = output.outputFile output.outputFile = new File(file.parent, file.name.replace("app-release.apk", newName)) } } 

但是2的返回值是null。

我也尝试设置属性和额外的属性:

 task.setProperty("vName", mNextVersionName) ext.vName = mNextVersionName extensions.extraProperties.set("vName", mNextVersionName) 

在2个任务中,让他们在release块没有运气。

有人有想法如何做到这一点?

Solutions Collecting From Web of "如何使用Gradle脚本自动增加和释放在Android Studio中签名的apk"

build.gradle ,这里是我的应用程序模块build.gradle的代码:

 apply plugin: 'com.android.application' apply from: 'versionalization.gradle' def genVersionName = VersionInfo.versionName def genVersionCode = VersionInfo.versionCode android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "com.vincestyling.exerciseapk" minSdkVersion 10 targetSdkVersion 22 versionName genVersionName versionCode genVersionCode } } android.applicationVariants.all { variant -> def taskSuffix = variant.name.capitalize() def assembleTaskName = "assemble${taskSuffix}" if (tasks.findByName(assembleTaskName)) { def processAPKTask = tasks.create(name: "process${taskSuffix}Apk", type: Copy) { variant.outputs.each { output -> from output.outputFile into output.outputFile.parent def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk" rename ~/(.+)/, newApkName } } tasks[assembleTaskName].finalizedBy processAPKTask } } 

在头部应用的versionalization.gradle是我用来增加VersionInfo ,然后返回两个值来使用。

 task VersionInfo { String FACTOR_KEY = "BUILD_NUMBER_FACTOR" File buildDir = file("build") buildDir.mkdir() File factorPropFile = new File(buildDir, "kbuildfactor.prop") Properties props = new Properties() if (factorPropFile.exists()) { props.load(new FileInputStream(factorPropFile)) } int buildNumberFactor = props.get(FACTOR_KEY) as Integer ?: 0 buildNumberFactor += 1 props.put(FACTOR_KEY, buildNumberFactor as String) props.store(new FileOutputStream(factorPropFile), null) String BASE_VERSION_NAME = "BASE_VERSION_NAME" String BASE_VERSION_CODE = "BASE_VERSION_CODE" File versionPropFile = file("versioning.properties") props.load(new FileInputStream(versionPropFile)) String baseVersionName = props.get(BASE_VERSION_NAME) as String Integer baseVersionCode = props.get(BASE_VERSION_CODE) as Integer ext.versionName = baseVersionName + "." + buildNumberFactor ext.versionCode = baseVersionCode * 1000 + buildNumberFactor } 

它很简单,阅读两个文件,以采取必要的领域来构build版本信息。

我们最后复制/重命名最终的APK。

此外,我首先获得了如下的复制/重命名部分,但当您有任何产品口味时,它将不起作用,我粘贴在这里作为另一种select。

 android.applicationVariants.all { variant -> variant.outputs.each {output -> def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk" def oldApkName = "app-${variant.buildType.name}.apk" def file = output.outputFile output.outputFile = new File(file.parent, file.name.replace(oldApkName, newApkName)) } } 

没有人回答,但我find了一个工作解决scheme。 我不喜欢它,它可以以更好的方式完成,但现在是我发现的唯一解决方法。

我还在寻找一个更好的解决scheme,如果你有一个,我会很乐意阅读和使用它,而不是我的。


所以,我在gradle.build文件中添加了一个新的任务,它只是复制“app-release.apk”文件,并使用清单文件中的值对其进行重命名:

 task copia{ dependsOn('assembleRelease') 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 mVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion) def pattern = Pattern.compile("versionCode=\"(\\d+)\"") def matcher = pattern.matcher(manifestText) matcher.find() def myVersionCode = Integer.parseInt(matcher.group(1)) copy { from 'app-release.apk' rename { String fileName -> fileName.replace('app-release.apk', 'com.walker93.catpadova-' + mVersionName + ' (' + myVersionCode + ').apk') } into 'apk_outputs' } } 

正如你所看到的,它只是一个复制和编辑版本的代码,在前面的两个任务中有一个copy {}函数(这里是文档 ),它读取versionName和versionCode的值而不增加它们,然后把它们放到新的文件名我将要取代。

这个任务仍然需要另外两个任务在那里,所以最后你会有3个任务。 在这个任务的第一行有dependsOn(assembleRelease) 。 这是非常重要的,它会运行所有其他的默认版本生成任务(包括我们的2个任务,增量和写入清单),生成更新和签名的apk。

现在,如果您尝试运行“生成签名的APK …”,您将会注意到此任务将无法运行。 相反,您将不得不手动启动它:

在这样的“运行configuration”中添加你的任务,然后当你想用自定义名称发布已签名的apk时,你应该能够从这里或者这里运行任务。 如果你想生成一个带有默认名字的已签名的apk(并且仍然增加versionName和versionCode),只需使用“生成签名的APK …”选项。

使用这种方法,不需要在文件的buildTypes部分添加代码。

要使用额外的属性扩展,你需要像这样定义它们:

 ext { mVersionCode = 0 mNextVersionName = "" } 

然后你可以在你的buildscript中自由地访问它们,就像你在上面的任务中使用它们一样。