Ich experimentiere mit einem neuen Android-Build-System, das auf Gradle basiert, und überlege, wie ich den Versionscode am besten automatisch erhöhen kann. Ich denke über zwei Optionen nach
- Erstellen Sie eine versionCode-Datei, lesen Sie die Nummer daraus, erhöhen Sie sie und schreiben Sie sie zurück in die Datei
- Analysieren Sie AndroidManifest.xml, lesen Sie den versionCode daraus, erhöhen Sie ihn und schreiben Sie ihn zurück in die AndroidManifest.xml
Gibt es eine einfachere oder geeignetere Lösung?
Hat jemand eine der Mentiod-Optionen verwendet und könnte sie mit mir teilen?
android
build
android-manifest
gradle
auto-increment
Sealskej
quelle
quelle
version.properties
Datei stackoverflow.com/a/21405744Antworten:
Ich habe mich für die zweite Option entschieden - das Parsen
AndroidManifest.xml
. Hier arbeitet ein Ausschnitt.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
wird in diesem Fall für Release-Builds freigegeben. Um es für Debug-Builds zu erhöhen, ändern Sie die task.name-Gleichung imtask.whenTaskAdded
Rückruf.quelle
Ich verwende diesen Code, um sowohl versionCode als auch versionName mithilfe eines Schemas "major.minor.patch.build" zu aktualisieren.
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' } }
quelle
Error:(48) Execution failed for task ':app:incrementVersionName'. > No match found
irgendwelche Ideen?android:versionName="0.0.0.1"
im Manifest festlegen, dass sonst keine Anzahl von Spielen erwartet wirdFull recompilation is required because 'BuildConfig.java' was changed.
Es scheint nicht das genaue Setup zu sein, das Sie verwenden, aber in meinem Fall werden die Builds von Jenkins ausgeführt und ich wollte $ BUILD_NUMBER als Versionscode der App verwenden. Das Folgende hat den Trick für mich dort gemacht.
defaultConfig { ... versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999 ... }
quelle
System.getenv()
im Gradle lesen.Ich verwende einen Zeitstempel für den Versionscode:
def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger() defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }
quelle
Wenn Sie den Versionscode in der Datei build.gradle halten, verwenden Sie das nächste Snippet:
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) }
quelle
versionCode 18
. Selbst wenn ich Ihren regulären Ausdruck auf einem Tester ("versionCode \d+"
) ausgeführt habe, stimmt er nicht überein.versionCode
und die Ziffer, da diese zusammen mit dem Text in ausgerichtet werdenversionName
.Gradle Erweiterte Build - Version ist ein Plugin für Android , das macht Erzeugung version und version automatisch. Es gibt viele Anpassungen. Hier finden Sie weitere Informationen dazu https://github.com/moallemi/gradle-advanced-build-version
quelle
So berücksichtigen Sie sowohl Produktaromen als auch Build-Typen und verwenden die Logik von @ sealskej zum Parsen von Manifesten:
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) } }
quelle
Inkrementieren Sie die VersionCode-Aufgabe (Ganzzahl):
Dies funktioniert durch Inkrementieren des Versionscodes
1
um beispielsweise:android:versionCode="1"
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) }
Inkrementiere VersionName Task (String):
Warnung: Muss einen
1
Punkt für Regex enthaltenDies funktioniert durch Inkrementieren des Versionsnamens
0.01
um beispielsweise: Sie können Ihr Inkrement einfach ändern und weitere Ziffern hinzufügen.android:versionName="1.0"
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) }
Vor:
<?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" >
Nach:
<?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" >
quelle
Wenn Sie Ihre
versionCode
In-gradle.build
Datei schreiben (meistens derzeit), finden Sie hier eine Problemumgehung. Ein bisschen dumm (Update "self"), aber es funktioniert!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' } }
quelle
Um den Beitrag von @ sealskej zu ergänzen, können Sie auf diese Weise sowohl Ihren Versionscode als auch Ihren Versionsnamen aktualisieren (hier gehe ich davon aus, dass Ihre Haupt- und Nebenversion beide 0 sind):
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) }
quelle
was ist damit? zu build.gradle hinzufügen (App-Modul)
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" }
quelle
(20160129 + 000000000) < (20160128 + 125959999)
Da ich mir die meisten Lösungen angesehen habe, waren sie nett, aber nicht genug. Deshalb habe ich dies geschrieben, ein Inkrement pro Multi-Deployment:
Dadurch wird der Build beim Kompilieren von Debug-Versionen und der Punkt und der Versionscode bei der Bereitstellung erhöht.
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 } }
quelle
Mein Ansatz ist es, die Manifestdatei aus dem Build-Ordner zu lesen und buildVersion herauszuholen, bevor ich einen Ordner lösche. Wenn die Aufgabe ein neues Manifest erstellt, ist meine inkrementierte buildVersion-Variable bereits vorhanden.
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 ]} }
quelle