over 4 years ago

アプリケーション開発では、本番用と開発環境用を分けてビルドを行うことがあります。例えば、サーバと連携するようなアプリでは接続先のテスト用のサーバと本番のサーバが異なるので、定数として定義したホスト名を修正してビルドするということがあります。

この修正は手動で行うことがありますが、何度も修正をする場合は面倒な作業になりがちです。また、修正箇所が複数に渡る場合はヒューマンエラーにより修正ミスが発生するリスクが高くなります。

このような問題をAntを使うことで解決することができます。

Antでプロジェクトをビルドできるようにする

$ cd android_project
$ android update project -p ./

これで、AndroidプロジェクトがAntでビルドできるようになります。

custom_rules.xmlを作成する

Antビルドが可能なプロジェクトは、build.xmlを持っているはずです。このxmlでは、custom_rules.xmlをインポートするようになっています。custom_rules.xmlは最初から存在しないので、新規作成します。

<?xml version="1.0" encoding="UTF-8"?>
<project
    name="MainActivity_">
 
    <!-- The configuration depends on "clean" because otherwise the build system will not detect changes in the configuration. -->
 
    <target
        name="buildDev"
        description="Build APK with developer settings i.e. logging on etc" > <!-- Name the build and give it a helpful description -->
 
        <antcall target="clean" /> <!-- clean out the /bin/ directory and delete all temp and cached files -->
 
        <antcall target="loadDevProperties" /> <!-- this is the business! here we are overwriting our config file -->
 
        <antcall target="debug" /> <!-- Build a debug APK and place it in /bin/ -->
    </target>
 
    <!-- The configuration depends on "clean" because otherwise the build system will not detect changes in the configuration. -->
 
    <target
        name="buildLive"
        description="Build APK with live settings i.e. logging off etc" >
 
        <antcall target="clean" />
 
        <antcall target="loadLiveProperties" />
 
        <antcall target="release" />
    </target>
 
    <property
        name="config.target.path"
        value="src/com/example/annotationdemo" /> <!-- This is like java variable creation. Here we setup the path of where the Config.java file is in your Android project -->
 
    <!-- Copy Config,java to our source tree, replacing custom tokens with values from ant.properties -->
 
    <target
        name="loadDevProperties"
        description="Use dev properties for logging / url etc" >
 
        <property
            name="config.properties.file"
            value="config.dev.properties" /> <!-- For loading dev properties we setup the variable 'config.properties.file' to be the dev properties -->
 
        <antcall target="copyProperties" /> <!--  We then copy from our /config/ to our project build /com.blundell.tut/ -->
    </target>
 
    <!-- Copy Config,java to our source tree, replacing custom tokens with values from ant.properties -->
 
    <target
        name="loadLiveProperties"
        description="Use live properties for logging / url etc" >
 
        <property
            name="config.properties.file"
            value="config.live.properties" />
 
        <antcall target="copyProperties" />
    </target>
 
    <target
        name="copyProperties"
        description="Copy the configuration file, replacing tokens in the file" >
 
        <copy
            encoding="utf-8"
            file="config/Config.java"
            overwrite="true"
            todir="${config.target.path}" > <!-- This is reading the template file and overwriting our build path equivalent file -->
 
            <filterset filtersfile="config/${config.properties.file}" /> <!-- Whilst it is overwriting we replace the placeholder with the values we set -->
        </copy>
 
        <tstamp />
 
        <echo message="Copy of properties finished. ${TSTAMP}" />
    </target>
 
</project>

重要な点は、copy要素です。これはantでファイルをコピーするための命令になります。このファイル中では、configディレクトリにある${config.properties.file}という変数に該当するファイルをベースにしてconfigディレクトリにConfig.javaを生成する処理が書かれています。

copyは、copyPropertiesターゲットにより実行されますが、copyPropertiesターゲットはまた別のターゲットから実行されます。例えば、開発環境用のビルドが行われるのならば、

buildDev -> loadDevProperties -> copyProperties -> copy

の順で実行されます。loadDevPropertiesの中では、${config.properties.file}の値がconfig.dev.propertiesであることが分かります。

テンプレートファイルと設定ファイルを書く

configディレクトリをプロジェクトルートに作成したら、三つのファイルを作成します。

GENERATED       = ** This build is currently using DEVELOPMENT properties **
CONFIG.LIVE             = false
CONFIG.SERVER           = http://development.server.net
CONFIG.GMAPS_API_KEY    = aaaaaaa
GENERATED       = ** This build is currently using LIVE properties **
CONFIG.LIVE             = true
CONFIG.SERVER           = http://live.server.net
CONFIG.GMAPS_API_KEY    = bbbbbbb
package com.example.annotationdemo;
 
// @GENERATED@
public class Config {
    public static final boolean LIVE = @CONFIG.LIVE@;
    public static final String SERVER = "@CONFIG.SERVER@";
    public static final String GMAPS_API_KEY = "@CONFIG.GMAPS_API_KEY@";
}

ビルドを行う

コマンドライン

開発環境ならば

$ ant buildDev

本番環境ならば

$ ant buildLive

Eclipse

Antのファイルを追加します。
Window->Show View->Ant->開いたウィンドで右クリック->Add BuildFiles

追加すると、幾つかのターゲットが表示されます。Android SDKが提供するものと、今回新たに作成したターゲットが表示されます。右クリックして Run As -> Ant build することでビルドを実行できます。


なお、補足になりますがアプリリリースに関してはキーストアの設定も別途必要になります。

参考:[TUT] Switching Android build constants using Ant

← Androidアプリケーションのユニットテストを自動化 HTTPマルチパートデータ送信 →