package com.kasperowski.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class BuildNumberExample extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View aboutView = aboutWithKeywordSubstitution();
setContentView(aboutView);
}
View aboutWithKeywordSubstitution() {
TextView aboutView = new TextView(this);
aboutView.setText("Build number: $Rev$");
return aboutView;
}
}And for bonus points, you could play some regex tricks or something to make the version number look like 42 instead of $Rev: 42$.But, uh-oh! That's the revision number for that file, not the global revision number for your whole project. So it's no good as a build number.
You could play other games, like using a serial number file and writing a script that increments the serial number every time you build. But then you'll have a different problem: my sandbox and your sandbox will increment the serial number independently, oftentimes using colliding serial numbers. It would be a sandbox-specific serial number, hardly a good way to identify a build. You could build a shared database column with a globally incrementing serial number, but that's overkill.
Instead, use
svnversion, a command line tool that returns the global version number of your repository. It is a stable, unique number that everyone can use, and it yields a true build identifier. At the command line, type svnversion, and you'll see your repository version number:$ svnversion
22To inject the svnversion number into your Android app's About screen, add a new resource to your strings.xml file:<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, BuildNumberExample!</string>
<string name="app_name">Build Number Example</string>
<string name="app_svnversion">foo</string>
</resources>Then, make sure you have an ant build script. I created my project using Eclipse, so I don't have a build script yet. Tell Android to create an ant build script for you:$ android update project --path .Now you have a build.xml file, and you can type things like ant clean, ant debug, and ant install to build and install your app. Test your build script to make sure it works:$ ant clean
Buildfile: C:\usr\local\workspace\build-number-example\build.xml
[setup] Project Target: Android 1.6
[setup] API level: 4
clean:
[delete] Deleting directory C:\usr\local\workspace\build-number-example\bin
[delete] Deleting directory C:\usr\local\workspace\build-number-example\gen
BUILD SUCCESSFUL
Total time: 46 seconds
$ ant install
Buildfile: C:\usr\local\workspace\build-number-example\build.xml
[setup] Project Target: Android 1.6
[setup] API level: 4
-compile-tested-if-test:
-dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: C:\usr\local\workspace\build-number-example\gen
[mkdir] Created dir: C:\usr\local\workspace\build-number-example\bin
[mkdir] Created dir: C:\usr\local\workspace\build-number-example\bin\classes
-resource-src:
[echo] Generating R.java / Manifest.java from the resources...
-aidl:
[echo] Compiling aidl files into Java classes...
compile:
[javac] C:\android-sdk-windows\platforms\android-1.6\templates\android_rules.xml:248: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 2 source files to C:\usr\local\workspace\build-number-example\bin\classes
-dex:
[echo] Converting compiled files and external libraries into C:\usr\local\workspace\build-number-example\bin\classes.dex...
[echo]
-package-resources:
[echo] Packaging resources
[aaptexec] Creating full resource package...
-package-debug-sign:
[apkbuilder] Creating BuildNumberExample-debug-unaligned.apk and signing it with a debug key...
[apkbuilder] Using keystore: C:\Documents and Settings\kasper\.android\debug.keystore
debug:
[echo] Running zip align on final apk...
[echo] Debug Package: C:\usr\local\workspace\build-number-example\bin\BuildNumberExample-debug.apk
install:
[echo] Installing C:\usr\local\workspace\build-number-example\bin\BuildNumberExample-debug.apk onto default emulator or device...
[exec] pkg: /data/local/tmp/BuildNumberExample-debug.apk
[exec] Success
[exec] 17 KB/s (13601 bytes in 0.781s)
BUILD SUCCESSFUL
Total time: 2 minutes 2 seconds
$ Add a new target to your build.xml file. This target executes svnversion and injects it into your strings.xml file.<target name="foo-update-svnversion">
<exec outputproperty="build.svnversion" executable="svnversion">
<arg line="-n -c" />
</exec>
<property name="match.start" value="<string name="app_svnversion">"/>
<property name="match.end" value="</string>"/>
<replaceregexp file="res/values/strings.xml"
match="${match.start}.*${match.end}"
replace="${match.start}${build.svnversion}${match.end}">
</replaceregexp>
</target>At the command line, invoke the new ant target and then look at your strings.xml file. You'll see the svnversion number in strings.xml:$ ant foo-update-svnversion
Buildfile: C:\usr\local\workspace\build-number-example\build.xml
[setup] Project Target: Android 1.6
[setup] API level: 4
foo-update-svnversion:
BUILD SUCCESSFUL
Total time: 2 seconds
$ cat res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, BuildNumberExample!</string>
<string name="app_name">Build Number Example</string>
<string name="app_svnversion">22</string>
</resources>
$ Now add some build targets to integrate your svnversion target with the default Android targets:<target name="foo-debug" depends="foo-update-svnversion">
<antcall target="debug"/>
</target>
<target name="foo-install" depends="foo-update-svnversion">
<antcall target="install"/>
</target>Finally, let's go back to your About screen. Add a method, aboutWithSvnVersion(), that grabs the svnversion resource and displays it on the screen:public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View aboutView = aboutWithSvnversion();
setContentView(aboutView);
}
View aboutWithSvnversion() {
TextView aboutView = new TextView(this);
String svnversion = getResources().getString(R.string.app_svnversion);
aboutView.setText("Build number: " + svnversion);
return aboutView;
}Build your Android app by typing ant foo-debug or ant foo-install. This does exactly what you want, and now the world is safe again.Resources:

1 comments:
Very helpful. Thank you
Post a Comment