はじめに
タイトルにあるように build.gradle.kts
をAndroidアプリ開発で使っていこうと思います.
また,マルチモジュールでプロジェクトを運用する際に同じような記述を共通化させる部分の紹介もしたいと思います.
最初,Android StudioでNew Projectすると build.gradle
というGroovyで記述されたスクリプトファイルが生成されます.
Groovyはあまり聞き慣れませんが,Javaから派生した動的型付けのプログラミング言語です.
build.gradle
でGroovyを使う際のイマイチな点として以下のものが挙げられると思います.
- 普段はJavaやKollinで開発するのに
build.gradle
だけGroovyで書かなければいけないく,JavaやKotlinで得た知見をbuild.gradle
に活かせない - 補完が効かない
大きくこの2つかなと個人的な見解として思っています.
DroidKaigi2019のセッションでも紹介されていました.
これを解決するためにbuild.gradle
をKotlinで記述してAndroidアプリ開発をしようというときに出てくるのがbuild.gradle.kts
です.今までGroovyで記述していたbuild.gradle
をKotlinで記述することができるようになります.
ではやっていきましょう.
Re:ゼロから始めるbuild.gradle.kts生活
やっていく
Step1
まずは,プロジェクト直下にbuildSrc
という名前でdirectoryを作ります.
その中に build.gradle.kts
ファイル を作って以下の中身を書きます.
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
書いたらsync nowします
色々ファイルが生成されます
Step2
次に buildSrc/src/main/java/dependencies
となるようにpackageを作ります
dependencies
の中に Libs.kt
作ります.
この中にはプロジェクトで必要なライブラリの依存関係を記述します.
よく Dep.kt
という名前で作りますが,今回は後々 Dependencies.kt
というファイルを作るときに名前が被るので適当に Libs.kt
という名前にしておきたいと思います.
Libs.kt
の中身はこのように書いていきます.ここはDroidKaigi/conference-app-2020のDep.ktが参考になると思います.
object Dep {
object Kotlin {
val stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61"
}
}
Step3
buildSrc
の中のbuild.gradle.kts
に追記
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
google() // 追記
}
dependencies {
implementation("com.android.tools.build:gradle:4.0.1") // 追記
}
com.android.tools.build:gradle
のバージョンは適宜変えてください.
これを入れることでこのあとマルチモジュールした際の依存関係の共通化をするコードを書くことができるようになります.
Step4
次にもともとbuild.gradle
にあった android
ブロックを共通化させるためのコードを書いていきます,
マルチモジュールでプロジェクトを作るとき,デフォルトではこの部分はすべてのモジュールで同じことを書かなければいけません.
そこで,buildSrc/src/main/java/dependencies
の中に BuildConfig.kt
というような名前でファイルを作成します.
中身は以下のように記述します.
package dependencies
import com.android.build.gradle.BaseExtension
object BuildConfig {
const val applicationId = "com.example.app"
const val versionCode = 1
const val versionName = "1.0"
const val androidTargetSdkVersion = 29
const val androidCompileSdkVersion = 29
const val androidMinSdkVersion = 23
const val buildToolsVersion = "29.0.3"
const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
const val consumerProguardFiles = "consumer-rules.pro"
}
fun BaseExtension.baseExtension() {
compileSdkVersion(BuildConfig.androidCompileSdkVersion)
buildToolsVersion(BuildConfig.buildToolsVersion)
defaultConfig {
minSdkVersion(BuildConfig.androidMinSdkVersion)
targetSdkVersion(BuildConfig.androidTargetSdkVersion)
versionCode = BuildConfig.versionCode
versionName = BuildConfig.versionName
testInstrumentationRunner = BuildConfig.testInstrumentationRunner
consumerProguardFiles(BuildConfig.consumerProguardFiles)
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
Step5
実際に使ってみます
appにある build.gradle
を build.gradle.kts
にrenameします.
中身は以下のように書き換えます.
一番下の dependencies
のブロックは今はおいておきます.
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
}
android {
baseExtension()
defaultConfig.applicationId = BuildConfig.applicationId
}
先程の BuildConfig.kt
で baseExtension
という名前で定義したものが使えています.
このように実際に使う際は android
ブロック内で baseExtension()
と一行書くだけで冗長だったコードを共通化することができています.
Step6
では次にdependencies
ブロックについてです.いつも使いたいライブラリの依存関係を定義するところですね.
ここも例えば features/home
と features/settings
みたいなモジュールを作った際に使うライブラリの依存関係が同じようになることがよくあります.
その部分もある程度のベースとなる依存関係は共通化させるようにします.
buildSrc/src/main/java/dependencies
に Dependencies.kt
を作ります.
中身は以下のように書いてみます.
fun Project.baseDependencies(additionalConfiguration: DependencyHandlerScope.() -> Unit) {
dependencies {
implementation(Libs.Kotlin.stdlib)
implementation(Libs.AndroidX.appCompat)
implementation(Libs.AndroidX.coreKtx)
implementation(Libs.AndroidX.constraint)
}
dependencies(additionalConfiguration)
}
private fun DependencyHandler.implementation(depName: Any) {
add("implementation", depName)
}
Step7
では,先程作った baseDependencies
を使ってみようと思います.
appの build.gradle.kts
に dependencies
を追加していきます.
中身を以下のようにします.
import dependencies.baseExtension
import dependencies.BuildConfig
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
}
android {
baseExtension()
defaultConfig.applicationId = BuildConfig.applicationId
}
baseDependencies {
}
いままで dependencies
で書いて中に implementation
を書いていましたが,どこでも使うようなベースになる依存関係はすべて baseDependencies
だけでかけるようになりました.
もちろん baseDependencies
の中でそのモジュール内でまた別に定義したい依存関係は implementation
で適宜追加できます.
おまけ
1つのライブラリを使いたいときにそれに関連する依存関係を複数まとめて書きたい場合があると思います.
そのときに, Dependencies.kt
に以下のようなコードを追加してみます.
fun DependencyHandler.groupie() {
implementation(Libs.Groupie.groupie)
implementation(Libs.Groupie.databinding)
}
そうすると,build.gradle.kts
で今回だとGroupieで使いたい複数の依存関係を以下のように一行ですっきり書くことができるようになります.
import dependencies.baseExtension
import dependencies.BuildConfig
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
}
android {
baseExtension()
defaultConfig.applicationId = BuildConfig.applicationId
}
baseDependencies {
groupie()
}
さいごに
こんな感じで今まで冗長だった依存関係の記述をすっきり,共通化させてしかもKotlinで書くことができるようになります.
みなさんも良き build.gradle.kts
生活を.