他者に自分の作ったアプリをビルドして試してもらいたい、というケースは公私ともに割とよくあるケースであり、そんな時にはできる限り手間がかからずに試せるようにしたいもの。
その点を考えると、Android Studioのビルド管理ツールに採用されているGradleは非常に便利だと感じる。
- 依存関係の解決が非常に楽かつ強力: Mavenリポジトリ+libs以下にjarを置く従来の方法に加え、以前はライブラリプロジェクトとしてimportする必要があったコンポーネント(GooglePlayServiceなど)まで解決できる。それらを設定ファイル(
build.gradle
)でほぼ同じように指定できる。 - Gradle自体のインストールを利用者に求めない。Gradleラッパーにより、Gradleがなければ自動的にダウンロードする。 (ref. http://www.gradle.org/docs/current/userguide/gradle_wrapper.html)
Gradleによるビルドでも残る問題
しかし、これで全てが解決かというとそうでもない。Android Studioにより自動生成される設定でアプリケーションのビルドを行うと、得てして以下のようにSDKパッケージ回りの依存関係でエラーが発生する。
> failed to find Build Tools revision 19.1.0 (設定で指定したバージョンのSDKビルドツールがインストールされていない)
> failed to find target android-19 (設定で指定したAPIレベルのSDKプラットフォームがインストールされていない)
ここらへんはまだ分かりやすいが、以下のように直接の原因が分かりづらい時もある。これは対応するリポジトリをあらかじめインストールしていないために起こるが、エラーメッセージからそれを読み取るのはなかなか難しい。
A problem occurred configuring project ':app'.
> Could not resolve all dependencies for configuration ':app:_debugCompile'.
> Could not find any version that matches com.android.support:support-v4:19.+.
Required by:
NeoPushSample:app:unspecified
> Could not find any version that matches com.google.android.gms:play-services:4.4.+.
Required by:
NeoPushSample:app:unspecified
(サポートライブラリ(上記では"support-v4:19.+.")の依存関係解決には"Android Support Repository"が、
GooglePlayServiceの依存関係解決には"Google Repository"が、それぞれ必要。)
これらの依存関係もGradle側で解決できると楽だと思っていたところ、既に同じようなことは考えられていた。感謝しつつ使用させてもらうことにした。
Gradle SDKManagerPlugin
Githubに丁寧に書いてあるが、一応このプラグインが行うことを整理したのが以下。
- SDKがインストールされていない場合、インストールする。
- Gradleの設定で指定したバージョンのビルドツールがインストールされていない場合、インストールする。
- Gradleの設定で指定したAPIレベルのプラットフォームがインストールされていない場合、インストールする。
- サポートライブラリ/GooglePlayServiceへの依存関係が存在して、かつ対応するリポジトリがインストールされていない場合、インストールする。
設定も非常に簡単で、プロジェクトルートのbuild.gradle
とappディレクトリのbuild.gradle
を少し書きかえるだけで良い。
(プロジェクトルートのbuild.gradle)
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.11.+'
// 追記
classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
}
}
...
(appディレクトリのbuild.gradle)
// 追記: "apply plugin: 'android'"より前で設定する
apply plugin: 'android-sdk-manager'
apply plugin: 'android'
...
これでビルドを実行した際に、インストールしていないコンポーネントが自動でインストールされる。
$ ./gradlew clean build
...
Android SDK not found. Downloading... // SDKがインストールされていない時
...
注意点
SDKがもともとインストールされていない場合は問題ないが、古いSDKがインストールされている場合には少し注意が必要。
SDKManagerPluginは、SDKがインストールされている場合(環境変数ANDROID_HOMEでインストール先が指定されているものとする)、そのSDKを使用して依存関係を解決しようとする。しかし、SDKのバージョンによっては要求されているパッケージが入っていない場合(ex. Google Repositoryが入っていない)があり、その際はエラーが発生する。
そのため既に開発環境が整備されている(=SDKインストール済み)人に試してもらう場合には、事前にSDKのアップデートをお願いする必要が出てくるかもしれない。homebrewなど別途パッケージ管理ツールを使っていればupdate自体は楽に行えるだろう。