Edited at

Android studioにおけるbuild.gradleの設定について

More than 3 years have passed since last update.


はじめに

最近Eclipse + ADTからstudioに移行した際にgradleの設定で色々行ったので個人メモとして残しておきます。

studioへの移行については他の方がまとめていらっしゃるので今回は特に触れませんが、私が行ったprojectでは単純にExportしても動かなかったので空のprojectを作ってソースやらリソースを移植しました。

http://techbooster.org/android/environment/16158/


環境情報

Android studio 1.4

gradle 1.3.1


Gradleについて

・Gradleは、Groovyで書かれているAntのよう汎用的にビルドができるツールです。

・Maven/Ivyリポジトリをサポートしているのでライブラリの依存関係の管理や追加などは自動で行ってくれる

・Antとも連携可能なようです。※いずれ機会があれば試してみます。


Androidアプリプロジェクトとファイルの構成

スクリーンショット 2015-10-16 20.37.06.png


アプリケーション内のbuild.gradleの設定

build.gradle

//プラグインの宣言
apply plugin: 'com.android.application'

//定数定義 gradleでは以下のようの定数を指定することができる
def VERSION_CODE = 1
def VERSION_NAME = "1.0.0"
def PACKAGE_NAME = "com.kazuhiro.helloworld"
def APPNAME = "Hello World"

//androidのビルド設定のメイン
android {
//アプリをビルドする際のSDKの設定
//compileSdkVersionやbuildToolsVsersionの記述
compileSdkVersion 23
buildToolsVersion "23.0.1"

//マニュフェストエントリ
defaultConfig {
applicationId PACKAGE_NAME
minSdkVersion 15
targetSdkVersion 22
versionCode VERSION_CODE
versionName VERSION_NAME
}

dexOptions{
jumboMode true

//gradleでビルドしてOutOfMemoryErrorが出るのであれば指定した方がよいです
javaMaxHeapSize "2g"
}

//jar ファイルに含まれるリソースファイルが複数あると重複エラーになるので
//packagingOptionsにて必要に応じて指定しておく。
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}

//lintオプション
//abortOnError falseにすることでlintエラーが発生してもエラーとならないようにする。
lintOptions {
abortOnError false
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}

//署名設定
signingConfigs {
//デバッグ用
debug {
storeFile file(debugKeystore)
}

//release 用
release {
storeFile file(productKeystore)
keyAlias productKeyAlias
storePassword productKeyPass
keyPassword productAliasPassword
}
}

productFlavors {
dev {
applicationId "${PACKAGE_NAME}.dev"
manifestPlaceholders = [appName: "${APPNAME} dev"];
}

product {
applicationId PACKAGE_NAME
manifestPlaceholders = [appName: "${APPNAME}"];
}
}

//ビルド定義
buildTypes{
debug{
debuggable true
applicationIdSuffix ".debug"
signingConfig signingConfigs.debug
}

release{
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
}

//ライブラリ依存関係
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}


各項目の説明

各項目の詳細は以下のとおりです。


プラグインの宣言

アプリケーションの場合



apply plugin: 'com.android.application

android ライブラリの場合



apply plugin: 'com.android.library'


def

以下のように指定することでbuild.gradlde利用できる定数を宣言できます。便利ですね :smile:

def VERSION_CODE = 1

def VERSION_NAME = "1.0.0"
def PACKAGE_NAME = "com.kazuhiro.helloworld"
def APPNAME = "Hello World"


android{}

Android Gradle Pluginでは、android {} ブロックにビルドの設定などを記述していきます。


Build Target

アプリビルド時のAndroid SDK及びToolのVersionを指定してください。

android {

//アプリをビルドする際のSDKの設定
//compileSdkVersionやbuildToolsVsersionの記述
compileSdkVersion 23
buildToolsVersion "23.0.1"

}


defaultConfig

ADTの場合は、Manifesfファイルに直接記述していましたが、build.gradleに記述しておくことでビルド時に自動でマニフェストに追加してくれます。

defaultConfig {

applicationId PACKAGE_NAME
minSdkVersion 15
targetSdkVersion 22
versionCode VERSION_CODE
versionName VERSION_NAME
}


packagingOptions

複数のLibraryが利用されるときに META-INF内のFileがConflictするため重複エラーにならないように以下のように指定することで回避することができます。必要に応じて適時追加してください。

 packagingOptions {

exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}


signingConfig

署名付きAPKファイルを生成する際のkeysotreの設定情報を記述する。debug/reelaseそれぞれ記述することができます。

パスワードは直接buld.gradleに記述せずに外部ファイルもしくは、gradle.propertiesに出しておいた方が良いですね。

今回はgradle.propertiesから読み込む例を記載しておきます。

//署名設定

signingConfigs {
//デバッグ用
debug {
storeFile file(debugKeystore)
}

//release 用
release {
storeFile file(productKeystore)
keyAlias productKeyAlias
storePassword productKeyPass
keyPassword productAliasPassword
}
}

gradle.properties

gradle.propertiesにプロパティとして以下のように定義しておきます

#デバッグ用のデバッグ署名

debugKeystore=../keystore/debug.keystore

#release用の署名情報
productKeystore=../keystore/product.keystore
productKeyAlias=com.kazuhiro.helloworld
productKeyPass=Hello
productAliasPassword=hello

外部ファイルの場合

http://www.slideshare.net/MakotoYamazaki/20150425-droidkaigi-gradle

のP15に記載されている方法でも取り込めるようです。そのうち試してみたいと思います。


productFlavors

開発版と商用版、有料版アプリ、無料版アプリなどをわけてapkを作成したい場合に、productFlavorsに定義することでそれぞれ作成したいアプリを作成することができます。

Product Flavorは任意の数だけ定義できるので、複数パターンのアプリを作る必要がある場合は便利な機能です。

今回は、開発用、商用版向けに変更したい場合を例に記載しておきます。

アプリケーションIDと、アプリ名を変更するようにしております。

 productFlavors {

dev {
applicationId "${PACKAGE_NAME}.dev"
manifestPlaceholders = [appName: "${APPNAME} dev"];
}

product {
applicationId PACKAGE_NAME
manifestPlaceholders = [appName: "${APPNAME}"];
}
}

上記に記載してますが、manifestPlaceholdersというものを使うことでManifestファイルにて変数を埋め込むことができます。

ここではアプリ名を変更する例を記載してます。

AndroidManifest.xml

<application
android:name=".BaseApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="${appName}" ←アプリ名
android:largeHeap="true"
android:theme="@style/AppTheme" >

<activity
android:name=".TopActivity"
android:label="${appName}" ←アプリ名
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


buildTypes

debuggableなどの設定や署名、proguardの利用などの設定を行うことができます。

実際にはproductFlavorsとの組み合わせでビルドすることになります。

applicationIdSuffixなどもかえられるのでdebug用、release用とで区別してapkを作成することができます。

buildTypes{

debug{
debuggable true
applicationIdSuffix ".debug"
signingConfig signingConfigs.debug
}

release{
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}


ソースやソースファイルの切替について

Product Flavorごとにディレクトリを分け、ソースファイル、画像などのリソースファイルなどをProduct Flavorごとに切り替えることもできます。

下記のようにmain と同じ階層にproductFlavorsで追加した開発用のdevと同じ名前のフォルダを作成して、javaファイル、リソースファイル、assetsの各種ファイルを配置しておくことでビルド時に選択したBuild Variantによって自動でおきかえてくれます。

drawbleのアイコンを開発用に用意することでアプリアイコンも商用用と開発用で切り替えることも可能です。

※ここでは、productはmainを利用するためproduct用のディレクトリは作成していませんが、必要であればproductのフォルダを作成してください。

スクリーンショット 2015-10-17 22.48.50.png


その他

アプリによりPUSH機能を使っている場合は、GCMのpermissionでパッケージ名.permisson.C2D_MESSAGEと記述する必要がありますが、manifestファイルにて以下のように指定おくことでFalvorによってパッケージ名が変わる場合も考慮することができます。

<permission android:name="${applicationId}.permission.C2D_MESSAGE"

android:protectionLevel="signature" />

ちなみにBroadcastReciver等のintentfileterのカテゴリ名等でパッケージを指定する場合も同様です。

<receiver

android:name="xxxxxx"
android:permission="com.google.android.c2dm.permisson.SEND"

<intent-filter>
<action android:name="com.google.android.c2dm.permisson.RECEIVE"
<category android:name="${applicationId}">
</intent-filter>

</receiver>


build.gradleの書式について

@opengl-8080さんがまとめられているので参考にしてみてください。

http://qiita.com/opengl-8080/items/a0bb31fb20cb6505188b


まとめ

・Antに比べて容易に設定できるので使いやすい

 Eclipse + ADTの時のantでごにょごにょやってた時よりもだいぶ楽ですね :smile:

 ステージング向けとか、開発環境向けとか、商用向けのアプリの切り替えやリソースファイルなども環境によって差し替えられるのでそのよう

 な開発をしている場合Eclipseで開発している場合はADTのサポートも終了するので早急にstudioへの移行を検討した方が良いかと思います。

・gradleでは上記以外の内容以外にも色々できるので今後はCI連携とか試してみたいです。


参考サイト

http://tools.android.com/tech-docs/new-build-system/user-guide

http://www.slideshare.net/MakotoYamazaki/20150425-droidkaigi-gradle