Android Gradle Plugin 入門
最近、俗にいうネイティブアプリの流れが社内で、巻き起こっているので
改めて Android Studioで使うGradleの説明をしていきたいと思います。
去年の「Android Advent Calendar 2013」で 「Gradleことはじめ」という記事を書きました
もう、いまさら新規のAndroid開発環境において、Eclipse + antを使いはじめる人は居ないと思いますが
当時は、Android開発においてのスタンダードがEclipse + antでした。
もう、Eclipseなんていう負の遺産は捨てて、Android Studioに移行しましょう。
Android Studioの良さは、今回は語り尽くせないので、他の方の記事を参考してください
では、今回のブログの趣旨である、Android Gradle Pluginを説明していきます
僕の考えた最強で平凡なbuild.gradle
細かい説明の前に、全体像はこんな感じになります。
buid.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
}
}
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
apply plugin: 'com.android.application'
def VERSION_CODE = 1
def VERSION_NAME = "1.0.0"
def PACKAGE_NAME = "jp.wasabeef.gradle"
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
useOldManifestMerger false
defaultConfig {
minSdkVersion 14
targetSdkVersion 20
versionCode VERSION_CODE
versionName VERSION_NAME
}
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
signingConfigs {
debug {
}
release {
// @See gradle.properties
// productKeyStore=../wasabeef.keystore
// productKeyAlias=wasabeef
// productKeyStorePassword=wasabeef
// productKeyAliasPassword=wasabeef
storeFile file(productKeyStore)
keyAlias productKeyAlias
storePassword productKeyStorePassword
keyPassword productKeyAliasPassword
}
}
buildTypes {
debug {
debuggable true
zipAlign true
applicationIdSuffix ".debug"
}
release {
debuggable false
zipAlign true
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
productFlavors {
develop {
applicationId "${PACKAGE_NAME}.develop"
}
staging {
applicationId "${PACKAGE_NAME}.staging"
}
production {
applicationId PACKAGE_NAME
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
repositories {
maven { url "https://repo.commonsware.com.s3.amazonaws.com" }
}
dependencies {
// compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:20.+'
compile 'com.android.support:support-v13:20.+'
compile 'com.google.android.gms:play-services:4.+'
compile 'com.squareup:otto:1.3.+'
compile 'com.squareup.okhttp:okhttp:2.0.+'
compile 'com.squareup.picasso:picasso:2.3.+'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
compile 'com.jakewharton:butterknife:5.1.+'
compile 'com.jakewharton.timber:timber:2.4.+'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-databind:2.2.+'
compile 'com.commonsware.cwac:richedit:0.3.0'
}
記述内容の説明
1. buildscript
ビルドスクリプト自体に依存関係がある場合などに
Pluginのdependenciesを登録しておきます
Androidの開発では、Android Gradle Pluginが必要となります
buildscript {
repositories {
// 最近は、Maven Centralではなく、BintaryのjCenterを指定するのが一般的に
jcenter()
}
dependencies {
// Android StudioのVersionによって、Required Versionが異なります
// バージョンを"+"で省略すると、常に最新のVersionを取得します
classpath 'com.android.tools.build:gradle:0.12.+'
}
}
2. allprojects
Android Studio及びGradleはマルチプロジェクトに対応しているので
ルートプロジェクトを含む全プロジェクトに適用されます
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
// EncodeをUTF-8にしときます
options.encoding = 'UTF-8'
}
}
3. apply plugin
Android Gradle Pluginの適用をします
apply plugin: 'com.android.application'
4. def
groovyの書き方になりますが、変数を定義します
def VERSION_CODE = 1
def VERSION_NAME = "1.0.0"
def PACKAGE_NAME = "jp.wasabeef.gradle"
5. android { }
Android Gradle Pluginでは、android {} ブロックに設定を書いていきます
android {
// 省略
}
6. Target
アプリをビルド時に利用される SDK及びToolのVersionを指定します
Android SDK Managerで最新をチェックして、出来るだけ最新を保ちましょう
チームで開発するときは、チームで同じVersionがインストールされてる必要があります
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
}
7. Manifest Merger
設定値をfalseにすることで AndroidManifestに決められた変数が使えるようになりました
例えば、後述するProduct Flavorsでパッケージ名をビルド時に決定するときに
AndroidManifestには、ビルド時に決定されたパッケージ名を使うことが出来ます
exp.
${applicationId} : パッケージ名の変数
android {
useOldManifestMerger false
}
8. Default Config
主に、Google PlayやAndroid Platform側が必要とするアプリのVersion設定
android {
defaultConfig {
// 最低動作 Version (API Level)
minSdkVersion 14
// 開発時のテスト済みであるVersionの指定
// これより新しいVersionが出た場合でも
// Android Platform側のデフォルト設定を出来るだけ変えないようにしてくれる
targetSdkVersion 20
// Google Playが識別するためのVersion
versionCode VERSION_CODE // 1
// アプリの利用者に触れることのある一般的なアプリのバージョン名
versionName VERSION_NAME // "1.0.0"
}
}
9. Packaging Options
Androidアプリ開発において、複数のLibraryが利用されるときに
META-INF内のFileがConflictするので、excludeしないとビルドが通らない場合があるため
必要なときに必要なものの除外をいれときます
android {
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
}
10. Signing Configs
アプリファイル(.apk)を作成するときに必要となるKeystoreの設定
Debug用や、Release用のConfigを用意しておきます
android {
signingConfigs {
debug {
}
release {
// gradle.propertiesにプロパティとして以下のように定義しておきます
// productKeyStore=../wasabeef.keystore
// productKeyAlias=wasabeef
// productKeyStorePassword=wasabeef
// productKeyAliasPassword=wasabeef
storeFile file(productKeyStore)
keyAlias productKeyAlias
storePassword productKeyStorePassword
keyPassword productKeyAliasPassword
}
}
}
11. Build Types
アプリファイル(.apk)を作成するときに必要となる設定値の定義
android {
buildTypes {
// debugビルド時に有効
debug {
// デバッグモード許可
debuggable true
// .apkの[最適化](http://qiita.com/kazuqqfp/items/8eae69e309c6ed75d661)
zipAlign true
// パッケージ名につけるサフィックス -> "jp.wasabeef.gradle.debug"
applicationIdSuffix ".debug"
// Version名につけるサフィックス
versionNameSuffix '-dev' -> "1.0.0-dev"
}
release {
// デバッグモード禁止
debuggable false
// .apkの[最適化](http://qiita.com/kazuqqfp/items/8eae69e309c6ed75d661)
zipAlign true
// ソースコードの難読化
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// signingConfigsで定義したKeystoreの設定を利用
signingConfig signingConfigs.release
}
}
}
12. Product Flavors
Android Gradle Pluginで最もCoolなプロダクトフレーバー
接続先の切り替えや、パッケージ名の変更、またはResourcesの変更をすることができます
android {
productFlavors {
develop {
applicationId "${PACKAGE_NAME}.develop"
}
staging {
applicationId "${PACKAGE_NAME}.staging"
}
production {
applicationId PACKAGE_NAME
}
}
}
13. Compile Options
利用するJavaのVersionを指定
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
14. Repositories
プロジェクト内で利用するMaven Repositoryを指定します
repositories {
maven { url "https://repo.commonsware.com.s3.amazonaws.com" }
}
15. Dependencies
コード上で、依存しているLibraryを記述します
Mavenと同じで、Meven CentralやjCenterから自動的に取得します
- antには出来ない
dependencies {
// compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:20.+'
compile 'com.android.support:support-v13:20.+'
compile 'com.google.android.gms:play-services:4.+'
compile 'com.squareup:otto:1.3.+'
compile 'com.squareup.okhttp:okhttp:2.0.+'
compile 'com.squareup.picasso:picasso:2.3.+'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
compile 'com.jakewharton:butterknife:5.1.+'
compile 'com.jakewharton.timber:timber:2.4.+'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-databind:2.2.+'
compile 'com.commonsware.cwac:richedit:0.3.0'
}
16. BuildConfig.java
Gradleでビルドした結果としてBuildConfig.javaが自動生成される
コード上で、接続環境先の判定やデバッグモードの状態判定や、VersionをUserAgentに利用するときなどに
static変数なので、便利に利用することができます。
/**
* Automatically generated file. DO NOT MODIFY
*/
package jp.wasabeef.gradle;
public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String PACKAGE_NAME = "jp.wasabeef.gradle";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "develop";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0.0";
}
独自設定を入れたい場合はbuildConfigFieldを使って、設定を追加することもできます
android {
productFlavors {
develop {
applicationId "${PACKAGE_NAME}.develop"
def gitSha = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
buildConfigField "String", "GIT_SHA", "\"${gitSha}\""
}
}
}
雑感
Android Gradle Pluginだけじゃなくて、他にもGradleのpluginがたくさんあるので
それらを利用することで、もっとCoolなbuild.gradleができると思います
ここで書いた設定は、基本的にProduct開発において最低減必要な 設定になりますので
参考にしてもらえたらと思います。
by @wasabeef_jp