16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Android + Gradle 探訪 - 前編: Groovy → KTS (Kotlin DSL) 書き換え

Last updated at Posted at 2022-03-03

droid_gr_kt2.png

最近は Gradle の構成を Groovy ではなく KTS (一連の Gradle の Kotlin DSL) で書いたり
buildSrc や Version Catalog に依存をまとめるのがナウそうですが,
Android Studio で作成した新規プロジェクトはシンプルな Groovy で記述されています.

Kotlin DSL などについて まったくわかっていないので (Groovy もだけど),
この機会に Empty Compose Activity Project を題材にして,
最近の Gradle の構成や記述について調べようと思いました.

:point_down: 後編:

ガイド

公式の移行ガイドがあるので見てみます:

あとは,具体例として KotlinConf 2018 での講演や:

gradle/kotlin-dsl-samples にあるサンプルの記述と照らし合わせるのも
わかりやすくてよさそうに思いました.

(この Repository は Archive されているのですけれど)

例として Empty Compose Activity の新規プロジェクトを作成してみます
(Android Studio Bumblebee 2021.1.1 Patch 2 + Gradle 7.0).

Empty Compose Activity

ごく標準的な,ルートには settings.gradle, build.gradle,
そして app レベルには app/build.gradle があるような構成ですね:

settings.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
/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
/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 ではできない記述を置き換える必要がありそうです:

  1. 文字列は Groovy ではシングルクォーテーションが使えましたが,Kotlin ではダブルクオーテーションである必要があります
  2. 関数呼び出しの括弧は Groovy では省略できましたが,Kotlin では省略できません
  3. 変数への代入は,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.gradlebuild.gradleapp/build.gradle
ひとつずつ順を追ってエラーをつぶしながら移行させていきましょう.

ext

まず,依存するライブラリ共通のバージョンを定義するのに
/build.gradle 内の ext というブロック1で Groovy では書かれていたわけですが,
これは使えないということで別の記述にしてみます.

build.gradle.kts
buildscript {
    extra.apply {
        set("compose_version", "1.0.1")
    }
}

こうするとおなじように Extra Properties を定義できるのですが,
大きなプロジェクトでは昨今の複数のモジュールの管理を考えて
別の便利なパターンを使うのもいいかなと思いました.
(後編の記事で紹介しています)

plugins

次に id "com.android.application" version "7.1.2" apply false とあって,
これはどういう書き方なのだろう…となるのですが,

これは id が単純な関数呼び出しで,
versionapply がその返り値の PluginDependencySpec に対する
infix の拡張関数の呼び出しとなるので
id だけを括弧で囲みます:

build.gradle.kts
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) となっているところが構文エラーで落ちるので,
これをどう書き換えるのかな,となります:

builde.gradle
task clean(type: Delete) {
    delete rootProject.buildDir
}

Custom Taskというやつで,
この例でいえば org.gradle.api.tasks.Delete で定義されたものを使うようになっているということです.

公式のガイドを見ると,tasks あたりを使う感じになるようなので,
完全に雰囲気で tasks.register<Delete>("clean") に書き換えます:

build.gradle.kts
tasks.register<Delete>("clean") {
    delete(rootProject.buildDir)
}

変更後同期して特にエラーがみられず,
Build > Clean Project が無事できれば OK です.

minifyEnabled

ここまで書き換えれば,プロジェクトルートにある build.gradle.kts
いい感じになったのではないかと思います.

ビルドが通ることを確認したら,
次は app レベルの app/build.gradle.kts もリネーム & 書き換えしていきます.

そうしていくと…
いきなり minifyEnabled がない! と怒られてしまうのですが,

app/build.gradle.kts
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 が見つからないよというエラーになるので,明示的に定義することにします.

app/build.gradle.kts
val compose_version: String by project

こうすれば使えるようになります.
Delegated Property なのが Kotlin な感じでオシャレ.

ビルドできるように

こうやってぬるりと書き換えていくことで,
ひとまず Empty Compose Activity Project については
Groovy → KTS へ移行することができたはずです.

さらに

さて,ext の節で書いたように,KTS の移行とは関係はないのですが
最近ではマルチモジュールでも共通で参照できるように
依存するライブラリの記述をまとめておくやりかたがよく使われているようです.

これについては後編の記事で紹介します:

  1. Extra Properties というようですね

16
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?