How to: subversion build number in your Android app

So you're building an Android app, and you want your app to display its build number on an About screen. You want the build number to be a unique identifier like the Subversion revision number. That's easy, you say: I'll build a simple About screen, put a TextView in it, and use Subversion keyword substitution, like this:
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
22
To 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 cleanant 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:

摘自:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值