Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

1.05. Android のビルドについて(Gradle)

Shinichiro Todaka edited this page Mar 6, 2014 · 10 revisions

1.05. Android のビルドについて(Gradle)

この章では Android のビルド、とりわけ、Gradle というビルドシステムを用いたビルドについて解説したいと思います。

記述内容は

  • Android Studio 0.4.3
  • Gradle 1.10

時点のものです。

目次


1.Gradle とは

Gradle とは、Java(JVM)環境におけるビルドシステムのことで、オープンソースプロジェクトとして無償で公開されています。
特長としては、ビルドの記述を XML のような構造ではなく、Groovy ライクな 独自の DSL を用い、スクリプトとして記述できる点です。
用意されているAPIを利用することで、強力な記述が可能となります。

必要環境

バージョン 1.5 以上の JVM を必要とします。

ビルドの構成要素

ビルドスクリプトを実際に触る前に、簡単にビルドの概念を説明します。

ビルドは1つ以上のプロジェクトで構成され、
そのプロジェクトは1つ以上のタスクで構成されます。
以下の様なケースを想像してもらえるとイメージが湧きやすいかと思います。

『アプリパッケージCを生成するために、A及びBのjarが必要で、
 そのA及びBのjarを作るためのモジュールがあり、
 それらを使って、アプリパッケージCを作るためのビルドを用意する』

A, B , Cそれぞれにモジュールがありそのビルドをビルドスクリプトで記述します。
また、タスクとはこれ以上分割できないような作業の単位を指します。

Gradle に触れてみよう

Hello world! の前に環境構築

練習だけなので、簡単に確認できる環境を用意します。
前章のAndroid Studioの項目で、既に Android Studio をインストール済みかと思います。
こちらに、Gradle が同梱されていますので、こちらを利用します。

説明は割愛しますが、別途、Gradle公式サイトよりダウンロードして、実行環境を構築して頂いても問題ありません。

プロジェクト構成

Android Studio でProjectを作ると、以下の様なツリー構造となります。 ビルドスクリプトは build.gradle となります。
2つありますが、ProjectRoot のものを使います。

├── .idea/
├── app/
│   ├── build/
│   ├── src/
│   ├── .gitignore
│   ├── app.iml
│   ├── build.gradle
│   └── proguard-rules.txt
├── gradle/
├── .gitignore
├── build.gradle <-- このファイルを使用します
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── MyApplication.iml
└── settings.gradle

改めて、Hello world!

build.gradleを開き、既に記載されているものはそのままにしておき、

task hello {
    doLast {
        println 'Hello world!'
    }
}

と末尾に追記してください。

実行

編集を終えましたら、Android Studio 同梱の Terminal から以下のコマンドを実行してみてください。
helloというタスクを実行するコマンドとなります。
(Terminal は左下のランチャ or Tools > Open Terminal より起動できます。馴染みのものでも構いません)

% ./gradlew -q hello

(Mac OS X / Linux プラットフォームの場合。Windows の場合は、gradlew.batを使用してください)

-q オプションは、Gradle のログメッセージを抑制し、引数で与えたタスクのみ、ログ出力を行います。
 今回は練習なので、解りやすいようにこのオプションを利用しています。
 (他のオプションは http://gradle.monochromeroad.com/docs/userguide/gradle_command_line.html を参照してください)
 
 また、gradlewに実行権限がない場合は、chmod +x gradlewとして、権限を付与して実行してみてください。

Hello world!

と出力されたでしょうか。

また、ショートカットを用いて、以下の様に記述することも可能です。

task hello << {
    println 'Hello world!'
}

記法

記法の全てをここでは伝えませんが、基本的なものを紹介します。

基本型
task hoge << {
    String fuga = 'fuga'
    int count = 9
    println 'hoge' + fuga + 'piyo'
	println count.toString()
}
% ./gradlew -q hoge                                                                                                
hogefugapiyo
9

繰り返し
task count << {
    3.times {
        println $it
    }
}
% ./gradlew -q count                                                                                                
0
1
2
依存関係の記述
task unlockDoor << {
    println "I unlock the door"
}
task enterMyRoom(dependsOn: unlockDoor) << {
    println "I'm home"
}
task relax(dependsOn: enterMyRoom) << {
    println "Relax..."
}
% ./gradlew -q relax                                                                                                
I unlock the door
I'm home
Relax...

% ./gradlew -q enterMyRoom                                                                                          
I unlock the door
I'm home

依存関係のあるタスクが先に実行されていることがわかるかと思います。

それでは、順番を並び替えた以下を実行してください。

task enterMyRoom(dependsOn: unlockDoor) << {
    println "I'm home"
}
task unlockDoor << {
    println "I unlock the door"
}
% ./gradlew -q enterMyRoom
-> ERROR!

エラーが起こって正常に実行できないようになったかと思います。 これは、未定義な unlockDoor を呼びだそうとする事により、起こるエラーです。

以下の様に、呼び出しを文字列にしてあげるだけで、遅延評価されるようになり、問題は起こらなくなります。

task enterMyRoom(dependsOn: 'unlockDoor') << {
    println "I'm home"
}
task unlockDoor << {
    println "I unlock the door"
}
% ./gradlew -q enterMyRoom
I unlock the door
I'm home

また、task定義とは別に依存関係を記述することも可能です。

task unlockDoor << {
    println "I unlock the door"
}
task enterMyRoom << {
    println "I'm home"
}
task relax << {
    println "Relax..."
}

unlockDoor.dependsOn enterMyRoom
relax.dependsOn unlockDoor, enterMyRoom
taskの前後に処理を差し込む
task sample << {
	println 'hoge'
}
sample.doFirst {
	println 'hello!'
}
sample.doLast {
	println 'fuga'
}
sample << {
	println 'piyo'
}
%  ./gradlew -q sample                                                                                                
hello! 
hoge
huga
piyo

doFirst, doLast<<) を用いることで、タスクの前後に処理を追加することが可能です。
複数の処理を同じ箇所に追加した場合は、定義された順番に実行されます。
また、定義済み task は、上記の様にドットアクセスでタスクを記述できます。

gradlew

上でgradlew(あるいはgradlew.bat)を用いてサンプルコードを実行していましたが、gradlewとはGradleラッパーといい、Gradleのビルド実行において推奨されている方法です。
gradlewの実体はシェルスクリプトです。
指定のバージョンのGradleをダウンロードし、それを用いてビルドを実行を行います。
なので、gradleではなく、gradlewを使うようにしておけば、環境に依存することがありません。

上記の観点より、gradlewをリポジトリに含めるようにしておいてください。
そうすることで、CIや公開リポジトリなりで配布した際にもバージョン依存で悩む必要がなくなるはずです。

なお、gradlewには実行権限が必要なので、無ければ設定してください。

Android Studio における Gradle

Android Studio のパッケージには Gradle が同梱しておりますので、 インストールしてすぐ利用することが可能です。

ビルドスクリプト

新規にプロジェクトを作成すると、以下の2つの build.gradle があると思います。

  • Project直下の build.gradle
  • app内の build.gradle

それぞれについて簡単に説明したいと思います。

Project直下の build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.8.+'
    }
}

allprojects {
    repositories {
        mavenCentral()
    }
}

buildscript / allprojectsrepositories は、外部からインポートする jar のリポジトリを指定します。
デフォルトで mavenCentral() が指定されています。
これで事が足りるとは思いますが、明示的に他のリポジトリも参照したい場合は以下のように記載します。

buildscript {
    repositories {
        mavenCentral()
        maven {
        	url "{TARGET_REPOSITORY_URL}"
        }
    }
    ...

dependenciesは依存関係を記述します。
外部のライブラリを読み込みたい場合はここに記述します。
すると、自動的にプロジェクトのExternal Librariesに読み込まれます。

デフォルトの様にmavenCentral() にあるものであれば、パスのみで記述できます。
また、リポジトリが無い jar を読み込みたい場合は、以下の様にします。
lib 以下の jar ファイルを読み込む設定です。

    dependencies {
        compile fileTree(dir:'libs', include: '*.jar')
    }
app内の build.gradle
apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile 'com.android.support:appcompat-v7:+'
}

apply plugin: 'android'はAndroidのプロジェクトであることを指します。

androidはビルドの情報を記載します。
defaultConfigはデフォルトの設定を記載し、
buildTypesはビルド毎の設定を記載します。

Android Studio の Project Structure との関係

setting.gradleというファイルを確認します。

include ':app'

と書かれているものがProject SettingsModulesに表示されます。
上記の例だと、appモジュールの設定が表示されます。

しかしながら、一部表示されないものがあったり、メリットは少ないので、build.gradleを編集することをおすすめします。

More infomation

Gradleの触りの部分を紹介しましたが、より理解を深めたい方は以下サイトを参照ください。

GitHub Pagesへ移行しましたmixi-inc.github.ioへお願いします。

Clone this wiki locally