Tech Racho エンジニアの「?」を「!」に。
  • 開発

Android Studioへ移行したお話(顧客納品、ビルド構成、Git管理の説明もあるよ!)

だいぶ出遅れた感がありますが、弊社で開発しているAndroidプロジェクトをようやくEclipseからAndroid Studio環境へ移行したのでその手順を書いてみたいと思います。

移行時のビルド環境は以下の通りです。

  • Android Studio 1.2
  • Gradle 2.2.1
  • Android Plugin 1.2.3

※Android Studio 1.3、Gradle 2.4、Android Plugin 1.3.0に更新後も問題なく動きました

EclipseからAndroid Studioへの移行に関する記事は既に色々と出回っていると思いますので、Android Studioへ移行しないといけない理由やHello World的な説明は省きます。

今回は移行対象のプロジェクトがサブモジュールの多い結構大きめのもの、かつ、リリースビルドは顧客環境で行う、など色々と考慮しないといけないことが多かったのでその辺りを中心に書いていきたいと思います。

Android Studioを始める上で知っておいた方が良いこと

まず初めに、基本的な部分なのですが、既存のブログなどの紹介記事にはあまり記載が無かったため、Android Studio(主にGradle)の勉強に必要なURLをまとめて紹介します。

Android Studio Overview
Configuring Gradle Builds
Android Plug-in for Gradle
上記の3つは基本的な部分なのでひとまず読んでおきましょう。
分量もさほど多くありません。

Gradle Plugin User Guide
Android Gradle Plugin DSL Reference
ここは超重要です。
build.gradleのandroid {} 内に出てくる名称やビルドタスク名称の意味が分からなかったら上記サイト内で検索してみましょう。

例えば以下のような単語などです。
assemble、clean、signingConfigs、productFlavors、buildTypes、applicationId、versionNameSuffix、zipAlignEnabledなど。

Gradle Documentation
上記の日本語訳サイト
Gradle Build Language Reference
ここはbuild.gradleのandroid {} 外のことで分からないことがあったら見る感じですかね。
allprojects、dependenciesなどの単語は上記サイトで調べてみてください。

Groovy Documentation
Groovy Language Documentation
ここも重要。
当初、Groovyのことを調べずに始めたら色々つまづきました。build.gradleの記法で疑問に思うことがあったらひとまずGroovyを調べてみましょう。(文字列のシングルクォートとダブルクォートの違いとか!)

Groovyの入門としては以下の記事が分かりやすかったです。
Groovyを知らない人のためのbuild.gradle読み書き入門

EclipseからAndroid Studioへの移行

今回のプロジェクトは以下の様な構成となっていて、ソース管理にはGitを使用しています。

  • メインのアプリケーションモジュール
  • Gitの別プロジェクトで管理しているサブモジュール
  • オープンソース等のサブモジュール等が複数

また、今回はEclipseプロジェクトからのimport機能的なのは使っていません。
最初はひとまずという感じでimportしてみようとしたのですが、盛大にエラーが出まくるし、ディレクトリ構成なども色々と変える必要があるため、地道に1モジュールずつ追加していく方法を取ることにしました。

移行前のEclipseのディレクトリ構成は以下のようになっています。
※Eclipseの設定ファイルその他諸々端折っています+実際にはもっとモジュールいっぱいあります

     / (Gitプロジェクトのルート)
     + MyApplication/ (アプリケーションのメインプロジェクト)
        + assets/
        + libs/
        + res/
        + src/
           + jp/
     + module1/ (サブモジュール)
        + libs/
        + res/
        + src/
           + jp/
     + module2/ (サブモジュール)
        + libs/
        + res/
        + src/
           + jp/
     + submodule/ (gitの別プロジェクトに登録されているサブモジュール)
        + libs/
        + res/
        + src/
           + jp/

それでは以下に移行手順を記載していきます。

Android Studioで空アプリが起動するようにする

いきなり元の大きなアプリを丸々移行して動くようにするのは大変です。
エラーが大量に出た際に原因が分かりにくくなってしまい、どのエラーから解消していけば良いのか分からなくなってしまうためです。

今回は地道に行きます。急がば回れです。

  1. Android Studioを起動し、Start a new Android Studio projectを選択します。
  2. Application name、Company Domain、Package nameなどを元のアプリケーションのメインモジュールに沿って入力し、Project locationやSDKも同様に設定して次へ進む。
  3. Add an activity to Mobileの項目はBlank Activityを選択し、Finishを押下します。

Android Studio-プロジェクト作成直後png

この時点でプロジェクトの構成は上記のようになっており、
Runを実行するとアプリが起動するはずです。

ひとまずここがスタートとなり、この「起動する」状態を維持しつつ、だんだんと元のアプリに近づけていきます。

サブモジュールを追加する

先ほど作成したメインのアプリケーションモジュール(上記の例だとapp)は一旦放置し、ひとまずはサブモジュールのビルドが通るようにします。

settings.gradleを見ると現時点では以下の内容しか記載されていません。
サブモジュールを追加していくとここの記述が増えていきます。

include ':app'
  1. File > New > New Moduleを選択しCreate New Module画面でMore ModulesからAndroid Libraryを選択し、Nextを選択しメインプロジェクト同様に各種値を設定して次に進みます。
  2. サブモジュールのAdd an activity to Mobileの項目は余計なファイルが生成されないようにAdd No ActivityにしてFinishを押下します。

Android Studio-サブモジュール追加直後
これでプロジェクトの構成が上記のようになり、settings.gradleを見ると以下のように変更されています。

include ':app', ':mylibrary'

ただし、このままでは追加したmylibraryにエラーがあったとしても起動できてしまったりします。
build.gradle (Module: app)のdependenciesに以下の文を追記すれば、mylibraryがビルドに失敗する状態だと起動ができなくなります。

compile project(':mylibrary')

この状態まで行ったら、いよいよ元アプリのサブモジュールファイルを移行していきましょう。

現時点だと以下のディレクトリ構成となっています。
※Projectの表示をAndroid→Projectに変更した表示になっています
Android Studio-サブモジュール追加直後-Dir

ファイルの移行

Eclipseからファイルを移行するには以下のことをします。

  • mylibraryのsrc/main/res配下のファイルを削除する
  • Eclipse側のsrc/jpをmylibraryのsrc/main/java/jpに移動する
  • Eclipse側のresをmylibraryのsrc/main/resに移動する
  • Eclipse側のlibs内にあるjarをmylibraryのlibsに移動する
  • Eclipse側のlibs/armeabiなどのsoが入ったディレクトリをmylibraryのsrc/main/jniLibsに移動する

Android Studio-サブモジュール移行後-Dir
こんな感じになります。

設定ファイルの修正など

New Moduleで追加した直後のbuild.gradle (Module: mylibrary)を開くと、dependenciesが以下のように記述されています。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}

以下の記述があれば、libsに置いたtest.jarは勝手に読み込まれます。libsにjarが存在しないなら消してしまって問題ありません。

compile fileTree(dir: 'libs', include: ['*.jar'])

以下の記述も、v7のサポートライブラリを使用していないなら消してしまいましょう。

compile 'com.android.support:appcompat-v7:22.2.0'

逆に、今まではEclipseのlibsディレクトリにandroid-support-v4などの Android Support Repositoryから取得出来るjarや、volleyのようなMaven Central(build.gradle (Project: MyApplication)に初期設定されているjcenterはMaven Centralのスーパセットとのこと)などから取得出来るjarが入っていたとします。

その場合は該当するjarは全て消し、build.gradle (Module: mylibrary)のdependenciesを以下のように書き換えます。
※バージョン番号は適宜読み替えて下さい

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:22.2.0'
    compile 'com.mcxiaoke.volley:library:1.0.17'
}

Google Play ServiceのAPIなどもGoogle Repositoryをインストールしていれば同様の設定で使用出来るようになります。
それ以外のライブラリに関しては、今まで通りlibsにjarを入れるようにします。

アプリの起動

Sync Project with Gradle Files(以後Sync)の実行をしてからアプリを起動してみましょう。
エラーが出ずに起動に成功したら、このサブモジュールの追加に関しては成功です。

ちなみに、サブモジュールのAndroidManifest.xmlに関しては基本的に初期状態のままで問題無いはずです。

もしもエラーが出た場合は、表示されたメッセージに従って修正を行いましょう。
そして、全てのサブモジュールを追加し終わるまで上記手順を繰り返します。

サブモジュールの各種管理に関して

サブモジュールの追加作業をしていると、サブモジュールを管理する上でいくつか気になる点が出てきたので、その時にした対処方法について記載していきます。

サブモジュールのディレクトリをもっと深くしたい

特にGitサブモジュールなどを使った場合に、リポジトリのルートにサブモジュールプロジェクトのルートが存在すれば良いですが、そうなっていない場合も多いかと思います。

例えばここに記載のようにlibrariesの下にサブモジュールを置くことにしてみます。

作成したサブモジュール(mylibrary2)をこのlibrariesの下に配置したら、settings.gradleを以下のように記載します。

include ':app', ':mylibrary', ':libraries:mylibrary2'

Syncすると以下のような状態になりました。
Android Studio-サブモジュール-library配下に設置

うまく行ったように見えます。
が、librariesというただのディレクトリがProjectに表示されていたり、実際にディレクトリを見るとappやlibrariesと同じ階層にmylibrary2のディレクトリが作成されていたり(もちろん、javaファイルなどはlibraries/mylibrary2の下にあります)、ちょっと気持ち悪い状態になってしまいました。

この辺り、あまり詳しく調べていないので他に良い方法があるかも知れませんが、ひとまずsettings.gradleを以下のようにすることでこの現象は解消できました。

include ':app', ':mylibrary', ':mylibrary2'
project(':mylibrary2').projectDir = new File('libraries/mylibrary2')

2行目の意味とかはこの辺りを参照して下さい。

再度Syncをすると、Projectからlibrariesが消えていると思います。
librariesや無駄に作成されていた方のmylibrary2ディレクトリに作成されていた.imlファイルも消えています。

サブモジュール単体でAndroid Studioのプロジェクト作れないんだけどどうすんの?

できないようです。(たぶん)

Gitでサブモジュールごとにプロジェクトを管理したい場合、一旦何かのアプリのサブモジュールとして作成し、そのサブモジュール部分だけを登録する、という形になるかと思います。

以後はそのアプリ、または別のアプリにサブモジュールとしてimportして開発を行う、と。

volleyなどはGitのプロジェクトルート=Android Studio(Gradle)のサブモジュールのルートな構成となっていました。

アプリのメインモジュールをAndroid Studioに移行する

長かったですが、遂にここまで来ました。

ひとまず、メインモジュールのソースなどを移行する前に、build.gradle (Module: app)のdependenciesに全サブモジュールと依存するライブラリが設定されており、かつ、アプリが起動出来る状態であることを確認して下さい。

これが問題なければおそらく期待通りに移行が完了するでしょう。

まずはサブモジュールの時と同じで、Eclipse側のsrc、res、libsなどをAndroid Studio側の該当のディレクトリにコピーしていきます。

次にメインモジュールのAndroidManifest.xmlもコピーしてapp/src/main/に置きます。
この時、Eclipseの時に指定していたversionCode、versionName、minSdkVersion、targetSdkVersionなどの設定はbuild.gradleで設定するためAndroidManifest.xmlからは消します。

dependencies以外いじっていなければ、build.gradle (Module: app)は以下の様な感じになっているはずです。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "jp.bpsinc.myapplication"
        minSdkVersion 10
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile project(':mylibrary')
    compile project(':mylibrary2')
}

ビルド構成など考え始めると設定を色々と追記する必要がありますが(その辺りは後述します)、ひとまずデバッグビルドでアプリを起動するだけならこれで問題ありません。

Sync後、アプリを起動できれば成功です。
エラーが出るようなら、またメッセージに従って1つずつ解消していきましょう。

アプリ起動までの移行はここまでで完了しましたが、今回は顧客環境でのリリースビルドや、各種ビルド構成なども考慮する必要がありました。

以降でそれを説明します。

その他考慮すること色々

Android Studioへ移行したソースのGitへのコミット

ファイルの変更履歴

EclipseからAndroid Studioへ移行すると、ディレクトリ構成が変わるため、mvで移動しないと今までの履歴が台無しになってしまいます。

ここも地道に頑張るしかありません。(SourceTreeとかだと、元ファイル全削除してから新ファイルを丸コピーしてもある程度は勝手にmv認識してくれたりします)

ディレクトリ構成

「EclipseからAndroid Studioへの移行」で移行した直後の状態は以下のような感じになっていると思います。(サブモジュールをlibraries配下にした場合)

     / (Gitプロジェクトのルート、かつ、Android Studioのプロジェクトルート)
     + app/ (メインモジュール)
        + libs/
        + src/
           + main/
              + assets/
              + java/
                 + jp/
              + jniLibs/
              + res/
     + libraries/ (サブモジュール)
        + mylibrary1/
           + libs/
           + src/
        + mylibrary2/
           + libs/
           + src/
        + gitsubmodule1/
           + libs/
           + src/
     - readme.txt
     - その他ファイル

で、途中で気付いたんですが、Android Studioのアプリのプロジェクト名称って親ディレクトリ名に勝手に書き換わっちゃうんですね。

なので、上記のディレクトリ構成だとGitプロジェクトのルートディレクトリ名称が違うとプロジェクト名が変わってしまいます。

開発メンバーや顧客先と用語を統一したりするためにも、以下のように変更しました。

     / (Gitプロジェクトのルート)
     + MyApplication/ (Android Studioのプロジェクトルート)
        + app/ (メインモジュール)
           + libs/
           + src/
        + libraries/ (サブモジュール)
           + mylibrary1/
           + mylibrary2/
           + gitsubmodule1/
     - readme.txt
     - その他ファイル

Gitへ登録するファイルについて

Android Studioでアプリのプロジェクト作成直後、プロジェクトルートに存在する.gitignoreは以下のような記述になっています。

.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

各モジュールの.gitignoreは以下のような記述になっています。

/build

.ideaディレクトリとか、各モジュールディレクトリにある.imlはAndroid Studioの設定ファイルなどのため、gradlew assembleコマンドなどでビルドを行うだけなら必要のないものです。

また、.imlやいくつかの設定ファイルは自動で再生成されたり、各個人環境の設定を保存しているだけだったりするので、Gitでファイル共有する必要は無かったりします。

これらファイルのどれを共有するかは各プロジェクトごとに判断が異なると思います。
※デフォルトの.gitignoreのままでも、無駄なファイルが共有されるだけで大きな不都合は無いと思います

ここに勉強の労力をかける気はしなかったので、細かく調べてはいません。
が、以下のサイトの説明が参考になったので紹介だけしておきます。
バージョン管理 ─プロジェクト管理ファイルについて[中編]
バージョン管理 ─プロジェクト管理ファイルについて[後編]

アプリの署名について

デバッグビルド

開発メンバーごとに別々のdebug.keystoreを使用していると、アプリの上書きインストールや
バージョンアップ確認などがやりづらくなるため、keystoreを共有する設定にしました。

debug.keystoreって何?という方はSigning in Debug Mode辺りを参照下さい。

まず、以下のようにdebug.keystoreを配置します。
※場所はどこでも良いです

     / (Gitプロジェクトのルート)
     + MyApplication/ (Android Studioのプロジェクトルート)
        + app/ (メインモジュール)
        + libraries/ (サブモジュール)
        + keystore/ (keystore配置ディレクトリ)
           - debug.keystore

そして、build.gradle (Module: app)に以下の指定を追記しています。

android {
    signingConfigs {
        debug {
            storeFile file("../keystore/debug.keystore")
        }
    }
}

これで、各開発メンバーが同じdebug.keystoreを共有することが出来ます。
詳細はSigning Configurationsに記載があります。

顧客先でのリリースビルド対応

今まで紹介してきた設定のままだと、リリースビルドを行おうとすると署名関連の情報がないためビルドに失敗します。

もちろんリリース用のkeystore(以後release.keystore)を設定してあげれば良いわけですが、今回はリリースビルドは顧客環境で行うため、release.keystoreは弊社では保持していません。

しかし、社内でもテストなどでリリースビルドを行いたいことはあります。
この時はもちろん適当にテスト用のrelease.keystoreを作成して使うわけですが、このファイルをdebug.keystore同様に保存してしまうと、納品物に混じってしまって顧客先で混乱を招く可能性があります。

そのため、今回は社内テスト用のrelease.keystoreをGit上はプロジェクトディレクトリ外に保存し、リリースビルドを行いたい時は手動でkeystoreディレクトリにコピーすることにしました。

同様に、顧客先でもrelease.keystoreをkeystoreディレクトリにコピーしてからビルドを実行する、という手順を踏んでもらいます。

     / (Gitプロジェクトのルート)
     + MyApplication/ (Android Studioのプロジェクトルート)
        + keystore/ (keystore配置ディレクトリ)
           - debug.keystore
     + testkeystore/ (test用keystore配置ディレクトリ)
        - release.keystore
        - release.properties

この時点でGit上は上記のようなディレクトリ構成になっています。
今回はrelease.keystore用のパスワードなどをpropertiesファイルに格納するようにしました。

release.propertiesの中身は以下の様になっています。

keyAlias=testkeystore
storePassword=testkeystore
keyPassword=testkeystore

そして、build.gradle (Module: app)には以下の内容を追記します。

android {
    signingConfigs {
        release {
            File keystoreFile = file('../keystore/release.keystore')
            File keystorePropertiesFile = file('../keystore/release.properties')
            storeFile file(keystoreFile)

            Properties properties = new Properties()
            keystorePropertiesFile.withInputStream {
                properties.load(it)
            }
            keyAlias properties.getProperty('keyAlias')
            storePassword properties.getProperty('storePassword')
            keyPassword properties.getProperty('keyPassword')
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

これでMyApplication/keystore内にrelease.keystoreとrelease.propertiesを入れておけば、リリースビルドも成功するようになります。

しかし、このままだとMyApplication/keystore内にrelease.keystoreとrelease.propertiesが無い状態でSyncしようとするとファイルが見つかりません、というエラーが発生してしまいます。

開発時はできればMyApplication/keystore内は空にしておき、社内でリリースビルドをしたい時に例外的にtestkeystore内のファイルを使用する、としたいです。
常にtestkeystore内のファイルを使用する状態だと、プロジェクトディレクトリ外にtestkeystoreを配置した意味が薄くなり、納品時にも間違いが発生する可能性が高くなるからです。

そのため、以下のようにbuidl.gradle (Module: app)を書き換えます。

android {
    signingConfigs {
        release {
            File keystoreFile = file('../keystore/release.keystore')
            File keystorePropertiesFile = file('../keystore/release.properties')
            if (keystoreFile.canRead() && keystorePropertiesFile.canRead()) {
                storeFile keystoreFile

                Properties properties = new Properties()
                keystorePropertiesFile.withInputStream {
                    properties.load(it)
                }
                keyAlias properties.getProperty('keyAlias')
                storePassword properties.getProperty('storePassword')
                keyPassword properties.getProperty('keyPassword')
            }
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

これでSync時にファイルが存在しなくてもエラーにならなくなりました。デバッグビルドを行うのみであれば、MyApplication/keystore内は空のままで問題ありません。

また、今回はpropertiesファイルを使用しましたが、keystoreのパスワードなどは環境変数やコマンドラインから読み込む方法もあります。詳細はここ

環境変数から読み込む。

storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

コマンドラインから読み込む。

storePassword System.console().readLine("\nKeystore password: ")
keyPassword System.console().readLine("\nKey password: ")

様々なビルド構成の作成

Build Variantsに記載の通り、Build Type + Product Flavorの組み合わせで様々なapkを出力することが出来ます。

Build Types

この項目では、debuggableなどのデバッグ関連の設定と、署名、proguardに加え、applicationIdSuffixやversionNameSuffixによるapplicationIdやバージョン名の変更ができます。

applicationIdSuffixでdebugの際に".debug"などと設定しておけばデバッグ版リリース版を同時にインストールすることが出来るようになります。
※今回のプロジェクトではapplicationIdの変更が許されなかったため使えませんでしたが・・・

versionNameSuffixもバージョン名がアプリの設定画面などで見れるようになっていれば、今インストールされているapkが何なのかパッと分かるようになって便利です。

Product flavors

この項目ではapplicationId、versionNameなどの変更に加え、targetSdkVersionなども変更が可能です。

独自定数の定義

Build TypeやProduct FlavorではbuildConfigFieldを使用してBuildConfigに定数を定義出来ます。

この機能を使うと、テスト用の機能のON/OFFを切り替えたり、開発環境と本番環境でURLを切り替えたりなどが簡単に行えます。

以下のような感じで書くと

android {
    productFlavors {
        dev {
            buildConfigField "String", "TEST_STRING", "\"TEST_STRING\""
            buildConfigField "boolean", "TEST_BOOLEAN", "true"
        }
    }
}

BuildConfigに以下の内容が追記されます。

  public static final String TEST_STRING = "TEST_STRING";
  public static final boolean TEST_BOOLEAN = true;

上記内容を見ればなんとなく分かるかと思いますが、String型を指定した際の「"\"TEST_STRING\""」を「"TEST_STRING"」と記載すると、BuildConfigが以下のように出力されてしまい、ビルドエラーになってしまうので注意が必要です。

  public static final String TEST_STRING = TEST_STRING;

ソースの切替

Sourcesets and Dependenciesに記載の通り、Product Flavorごとにディレクトリを分け、ソースファイル自体を切り替えることも可能です。

ただ、ファイルが分かれていると修正漏れなどが発生する可能性が高いかな?と思い、今回のプロジェクトではこの機能は使いませんでした。

バージョン名の付け方とか

テスト中などに不具合が見つかる度にビルドを繰り返すと、市場リリースバージョンは同じでもテスト用のapkは複数作成されることになります。

この時にバージョン名の末尾にビルド番号が表示されていると、バグが発生した際などに弊社-顧客間で意思の疎通が取りやすくなります。

今回は以下の様な感じでバージョン名を付けてみました。
Product Flavorsは開発環境、ステージング環境、本番環境向けの3つを作成しています。
※必要な部分のみ記載しています

def VERSION_NAME = "1.0.0"
def BUILD_NUM = "1"

android {
    defaultConfig {
        versionName VERSION_NAME
    }
    buildTypes {
        debug {
            versionNameSuffix "." + BUILD_NUM + "-debug"
        }
    }
    productFlavors {
        dev {
            versionName "dev-" + VERSION_NAME
        }
        stg {
            versionName "stg-" + VERSION_NAME
        }
        prod {
        }
    }
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def dir = output.outputFile.parent
            def flavorName = variant.productFlavors[0].name
            def apkNameSuffix = variant.versionName

            if (variant.buildType.name.equals("release")) {
                apkNameSuffix = apkNameSuffix + "." + BUILD_NUM
            }
            if (flavorName.equals("prod")) {
                apkNameSuffix = "prod-" + apkNameSuffix
            }
            output.outputFile = new File(dir, "MyApplication-${apkNameSuffix}.apk")
        }
    }
}

こうすると、以下のように出力されます。

Build Variant バージョン名 APK名称
devDebug dev-1.0.0.1-debug MyApplication-dev-1.0.0.1-debug.apk
devRelease dev-1.0.0 MyApplication-dev-1.0.0.1.apk
stgDebug stg-1.0.0.1-debug MyApplication-stg-1.0.0.1-debug.apk
stgRelease stg-1.0.0 MyApplication-stg-1.0.0.1.apk
prodDebug 1.0.0.1-debug MyApplication-prod-1.0.0.1-debug.apk
prodRelease 1.0.0 MyApplication-prod-1.0.0.1.apk

BUILD_NUMはテスト期間中に再ビルドなどを行う度に1ずつ上げていきます。

本当はprodRelease以外はリリースビルドであってもバージョン名にBUILD_NUMを付与したかったのですが、applicationVariants.allの中だとversionNameの書き換えはできないためうまく行きませんでした。

この辺り、もっとうまいやり方知っている方がいましたら教えていただけると嬉しいです。

リリースビルドは本番向け以外いらないんだけど?

build.gradle (Module: app)に以下の記述を追記すればBuild Variantから開発環境(dev)とステージング環境(stg)のリリースビルド設定を消せます。

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals("release")) {
            if (variant.flavors[0].name.equals("stg")
                    || variant.flavors[0].name.equals("dev")) {
                variant.setIgnore(true);
            }
        }
    }
}

ビルド環境に関して

Gradleラッパー

Gradlewラッパーの詳細はここを見て下さい。

     + MyApplication/ (Android Studioのプロジェクトルート)
        + gradle/
           + wrapper/
              - gradle-wrapper.jar
              - gradle-wrapper.properties
        - gradlew
        - gradlew.bat

サイトに記載の通り、ラッパーにより上記ファイルが生成され、これをGitなどのバージョン管理システムに登録しておくことにより、別の環境での環境構築が非常に楽になります。

Gradleのバージョンを更新する際もgradle-wrapper.propertiesを書き換えるだけでできます。

ビルドに必要な最小環境

今回のプロジェクトで開発者以外や、顧客環境などでビルドしてもらう際に整えてもらう必要のある最小環境は以下の通りでした。(Android Studioは必要ありません)
※プロジェクトにGradleラッパーが保存されている前提となります。

  • Java SE Development Kit 7のインストールと環境変数JAVA_HOMEの設定
  • Android SDKのインストールと環境変数ANDROID_HOMEの設定
  • Android SDK Managerで以下の項目をインストール
    • Android SDK Tools
    • Android SDK Platform-tools
    • Android SDK Build-tools (対象のバージョン)
    • SDK Platform (対象のAPI Level)
    • Android Support Repository
    • Google Repository

Google Repositoryなどは使用していなければインストールする必要はないかも知れません。

この状態でAndroid Studioのプロジェクトルートをコマンドラインで開き、「gradlew clean assembleDevDebug」などと打てばビルドが出来ます。
ここの62.2.にあるように、Gitなどを経由すると実行権限がなくて失敗する可能性があるので注意

Android Pluginの仕様で説明が載ってない部分があるんですけど?

こういう時は仕方ないのでソースを覗きましょう。
ちらっと覗くだけでも雰囲気が掴めます。

Windows環境のデフォルト仕様でAndroid Studioを使っている場合は、build.gradle内で気になる名称(productFlavorsとか)に対してJump to Source(F4)とかCtrl+左クリックとかしてソースを覗いて見ましょう。

ソースファイルの実体は以下のディレクトリとかに入っています。
 {Android Studioインストールディレクトリ}/gradle/m2repository/com/android/tools/build/gradle-core/

まとめ

途中から大分とりとめのない内容になってしまいましたが、以上が今回の移行作業で行った(学んだ)内容となります。

正直今ではもうEclipseに戻る気が全くしません。
ビルド構成を色々いじれるのも素敵ですが、操作に慣れるとIDEとしてもEclipseより良い点が多いように思います。

ひとまず今回の件で自分が学んだ内容は全て出し切ったつもりなので、みなさんも「俺の最強Gradle設定」を是非晒してもらえると嬉しいなーと思います。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。