最近は Gradle の構成を Groovy ではなく KTS (一連の Gradle の Kotlin DSL) で書いたり
buildSrc
や Version Catalog に依存をまとめるのがナウそうですが,
Android Studio で作成した新規プロジェクトはシンプルな Groovy で記述されています.
Kotlin DSL などについて まったくわかっていないので (Groovy もだけど),
この機会に Empty Compose Activity
Project を題材にして,
最近の Gradle の構成や記述について調べようと思いました.
後編:
ガイド
公式の移行ガイドがあるので見てみます:
あとは,具体例として KotlinConf 2018 での講演や:
gradle/kotlin-dsl-samples にあるサンプルの記述と照らし合わせるのも
わかりやすくてよさそうに思いました.
(この Repository は Archive されているのですけれど)
例
例として Empty Compose Activity
の新規プロジェクトを作成してみます
(Android Studio Bumblebee 2021.1.1 Patch 2 + Gradle 7.0).
ごく標準的な,ルートには settings.gradle
, build.gradle
,
そして app
レベルには app/build.gradle
があるような構成ですね:
settings.gradle
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "myproj20220215"
include ':app'
build.gradle
buildscript {
ext {
compose_version = '1.0.1'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.1.1' apply false
id 'com.android.library' version '7.1.1' apply false
id 'org.jetbrains.kotlin.android' version '1.5.21' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 31
defaultConfig {
applicationId "io.github.manganoito.myproj20220215"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
}
基本
これをどうやって KTS にするかというと,
まず,Groovy では可能で,Kotlin ではできない記述を置き換える必要がありそうです:
- 文字列は Groovy ではシングルクォーテーションが使えましたが,Kotlin ではダブルクオーテーションである必要があります
- 関数呼び出しの括弧は Groovy では省略できましたが,Kotlin では省略できません
- 変数への代入は,Groovy では
=
を省略できましたが,Kotlin では省略できません
▲ Prepare your Groovy scripts | Migrating build logic from Groovy to Kotlin から
ところで (1) は自明なのですが,(2), (3) が微妙にわからないですよね.
どれが関数呼び出しで,どれが代入なのかがパッと見わからない.
(雰囲気でわかるといえばわかるのですが)
ひとつは Go To
> Implementation(s)
などで調べてやっていくことですが…
もうひとつとしては,
ここで大まかに書き換えたとしても結局エラーは出てしまうので,
先に進んでしまって KTS にしてから構文エラーをひとつずつ潰していく……
という地道な作業を行うほうが楽そうです.
(もちろん git
などで管理して失敗したら退却する準備をしておいたうえで)
なので,おおまかに書き換えたら次のステップに進んでしまいます.
Groovy → KTS として扱うようにするには?
さて,Groovy から KTS として扱ってもらうには
*.gradle
を *.gradle.kts
にリネームすれば OK です.
よくわからないけど便利にできている.
しかしながら,リネームしたあとに前の段階で構文をあわせたのにもかかわらず,
まだビルドが通らない箇所があることに気づくと思います.
それぞれ対応する Kotlin DSL の記述に調整してビルドが通るようにしていきます.
settings.gradle
→ build.gradle
→ app/build.gradle
と
ひとつずつ順を追ってエラーをつぶしながら移行させていきましょう.
ext
まず,依存するライブラリ共通のバージョンを定義するのに
/build.gradle
内の ext
というブロック1で Groovy では書かれていたわけですが,
これは使えないということで別の記述にしてみます.
buildscript {
extra.apply {
set("compose_version", "1.0.1")
}
}
こうするとおなじように Extra Properties を定義できるのですが,
大きなプロジェクトでは昨今の複数のモジュールの管理を考えて
別の便利なパターンを使うのもいいかなと思いました.
(後編の記事で紹介しています)
plugins
次に id "com.android.application" version "7.1.2" apply false
とあって,
これはどういう書き方なのだろう…となるのですが,
これは id
が単純な関数呼び出しで,
version
と apply
がその返り値の PluginDependencySpec
に対する
infix
の拡張関数の呼び出しとなるので
id
だけを括弧で囲みます:
plugins {
id("com.android.application") version "7.1.2" apply false
id("com.android.library") version "7.1.2" apply false
id("org.jetbrains.kotlin.android") version "1.5.21" apply false
}
task
task clean(type: Delete)
となっているところが構文エラーで落ちるので,
これをどう書き換えるのかな,となります:
task clean(type: Delete) {
delete rootProject.buildDir
}
Custom Taskというやつで,
この例でいえば org.gradle.api.tasks.Delete
で定義されたものを使うようになっているということです.
公式のガイドを見ると,tasks
あたりを使う感じになるようなので,
完全に雰囲気で tasks.register<Delete>("clean")
に書き換えます:
tasks.register<Delete>("clean") {
delete(rootProject.buildDir)
}
変更後同期して特にエラーがみられず,
Build
> Clean Project
が無事できれば OK です.
minifyEnabled
ここまで書き換えれば,プロジェクトルートにある build.gradle.kts
は
いい感じになったのではないかと思います.
ビルドが通ることを確認したら,
次は app
レベルの app/build.gradle.kts
もリネーム & 書き換えしていきます.
そうしていくと…
いきなり minifyEnabled
がない! と怒られてしまうのですが,
android {
buildTypes {
release {
- minifyEnabled = false
+ isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
単に isMinifyEnabled
になっているので名前を変えてあげます.
compose_version
更に "androidx.compose.ui:ui:$compose_version"
みたいにしているところで,さっき変えたばかりの Extra Property が見つからないよというエラーになるので,明示的に定義することにします.
val compose_version: String by project
こうすれば使えるようになります.
Delegated Property なのが Kotlin な感じでオシャレ.
ビルドできるように
こうやってぬるりと書き換えていくことで,
ひとまず Empty Compose Activity
Project については
Groovy → KTS へ移行することができたはずです.
さらに
さて,ext
の節で書いたように,KTS の移行とは関係はないのですが
最近ではマルチモジュールでも共通で参照できるように
依存するライブラリの記述をまとめておくやりかたがよく使われているようです.
これについては後編の記事で紹介します:
-
Extra Properties というようですね ↩