现在的位置: 首页 > 综合 > 正文

How to: subversion build number in your Android app

2018年02月10日 ⁄ 综合 ⁄ 共 6178字 ⁄ 字号 评论关闭
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:

摘自:

抱歉!评论已关闭.