ビルド構成を Groovy から Kotlin に移行する

Android Gradle プラグイン 4.0 では、Gradle 構成ファイルで従来使用されているプログラミング言語 Groovy に代わるものとして、Gradle ビルド構成に Kotlin を使用するためのサポートが追加されました。

Kotlin の方が読みやすく、コンパイル時のチェックと IDE のサポートが優れているため、Gradle スクリプトの記述に関しては Groovy よりも Kotlin が優先されます。

Kotlin は現在、Groovy と比較して Android Studio のコードエディタとの統合に優れていますが、Kotlin を使用したビルドは Groovy を使用したビルドよりも遅くなる傾向があるため、移行するかどうかを決定する際はビルドのパフォーマンスを考慮してください。

このページでは、Android アプリの Gradle ビルドファイルを Groovy から Kotlin に変換するための基本情報について説明します。より包括的な移行ガイドについては、Gradle の公式ドキュメントをご覧ください。

タイムライン

Android Studio Giraffe 以降、新しいプロジェクトはビルド構成にデフォルトで Kotlin DSL(build.gradle.kts)を使用します。構文のハイライト表示、コード補完、宣言へのナビゲーションなど、Groovy DSL(build.gradle)よりも優れた編集エクスペリエンスを提供します。詳細については、Gradle Kotlin DSL Primer をご覧ください。

よく使用する用語

Kotlin DSL: 主に Android Gradle プラグイン Kotlin DSL のことを指します。基となる Gradle Kotlin DSL を指すこともあります。

この移行ガイドでは、「Kotlin」と「Kotlin DSL」は同じ意味で使用されています。同様に、「Groovy」と「Groovy DSL」は同じ意味で使用されます。

スクリプト ファイルの名称

スクリプト ファイルの拡張子は、ビルドファイルが記述されている言語に基づきます。

  • Groovy で記述した Gradle ビルドファイルは、ファイル名拡張子 .gradle を使用します。
  • Kotlin で記述した Gradle ビルドファイルは、ファイル名拡張子 .gradle.kts を使用します。

構文を変換する

Groovy と Kotlin の構文には一部異なる点があるため、それらの違いをビルド スクリプト全体に反映する必要があります。

メソッド呼び出しにかっこを追加する

メソッド呼び出しのかっこは、Groovy では省略できますが Kotlin では必須です。構成を移行するには、かっこが省略されているメソッド呼び出しにかっこを追加します。Groovy で設定を構成する場合のコードは次のようになっています。

compileSdkVersion 30

これを Kotlin で記述すると次のようなコードになります。

compileSdkVersion(30)

代入呼び出しに = を追加する

Groovy DSL では、プロパティを代入する際の代入演算子 = を省略できますが、これは Kotlin では必須です。Groovy でプロパティを代入する場合のコードは次のようになっています。

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

Kotlin でプロパティを代入するには次のようなコードを記述します。

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

文字列を変換する

Groovy と Kotlin では、文字列に関して以下のような違いがあります。

  • 文字列の二重引用符: Groovy では一重引用符を使用して文字列を定義できますが、Kotlin では二重引用符を使用する必要があります。
  • ドット表記の文字列補間: Groovy ではドット表記の文字列補間に接頭辞 $ を使用できますが、Kotlin ではドット表記を中かっこで囲む必要があります。たとえば、Groovy では次のスニペットのように $project.rootDir を使用できます。

        myRootDirectory = "$project.rootDir/tools/proguard-rules-debug.pro"
        

    一方、Kotlin では project.rootDir ではなく projecttoString() を呼び出します。ルート ディレクトリの値を取得するには、${project.rootDir} のように中かっこで囲みます。

        myRootDirectory = "${project.rootDir}/tools/proguard-rules-debug.pro"
        

    詳細については、Kotlin ドキュメントの文字列テンプレートをご覧ください。

ファイル拡張子を変更する

コンテンツを移行する際に、各ビルドファイルに .kts を追加します。たとえば、ビルドファイル settings.gradle を選択したら、ファイル名を settings.gradle.kts に変更し、ファイルの内容を Kotlin に変換します。各ビルドファイルの移行後もプロジェクトがコンパイルされていることを確認します。

まずは小さなファイルの移行から始めて作業に慣れてください。1 つのプロジェクトに Kotlin と Groovy のビルドファイルを混在させることもできるため、時間をかけて慎重に移行してください。

defval または var で置き換える

Kotlin で変数を定義できるよう、defval または var で置き換えます。Groovy では次のように変数を宣言します。

def building64Bit = false

これを Kotlin で記述すると次のようなコードになります。

val building64Bit = false

ブール値プロパティに接頭辞 is を追加する

Groovy では、プロパティ名に基づいてプロパティ推定ロジックを使用します。ブール値プロパティ foo の場合、推定メソッドgetFoosetFoo、または isFoo になります。Kotlin では推定メソッドがサポートされていないため、プロパティ名を推定メソッド名に変更する必要があります。たとえば、buildTypes DSL ブール値要素には、接頭辞 is を追加する必要があります。Groovy では、次のようなコードでブール値プロパティを設定します。

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            ...
        }
        debug {
            debuggable true
            ...
        }
    ...

これを Kotlin で記述すると次のようなコードになります。プロパティには接頭辞 is が追加されています。

android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            ...
        }
        getByName("debug") {
            isDebuggable = true
            ...
        }
    ...

リストとマップを変換する

Groovy と Kotlin では、リストとマップを定義する構文が異なります。Groovy では [] を使用しますが、Kotlin では listOf または mapOf を使用してコレクション作成メソッドを明示的に呼び出します。移行時には、[]listOf または mapOf に置き換える必要があります。

Groovy では、次のようなコードでリストを定義します。

jvmOptions += ["-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError</code>"]

これを Kotlin で記述すると次のようなコードになります。

jvmOptions += listOf("-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError")

Groovy では、次のようなコードでマップを定義します。

def myMap = [key1: 'value1', key2: 'value2']

これを Kotlin で記述すると次のようなコードになります。

val myMap = mapOf("key1" to "value1", "key2" to "value2")

ビルドタイプを設定する

Kotlin DSL で暗黙的に使用できるビルドタイプは debug と release のみです。これら以外のすべてのカスタム ビルドタイプは手動で作成する必要があります。

Groovy では、debug や release 以外にも、先に作成していなくても使用できるビルドタイプがあります。次のコード スニペットに、Groovy でビルドタイプ debugreleasebenchmark を使用する構成を示します。

buildTypes {
 debug {
   ...
 }
 release {
   ...
 }
 benchmark {
   ...
 }
}

Kotlin で同等の構成を作成するには、benchmark ビルドタイプを明示的に作成する必要があります。

buildTypes {
 debug {
   ...
 }

 release {
   ...
 }
 register("benchmark") {
    ...
 }
}

buildscript から plugins ブロックに移行する

ビルドで buildscript {} ブロックを使用してプロジェクトにプラグインを追加している場合は、代わりに plugins {} ブロックを使用するようにリファクタリングする必要があります。plugins {} ブロックを使用すると、プラグインの適用が容易になり、バージョン カタログと効率的に連携できます。

また、ビルドファイルで plugins {} ブロックを使用すると、ビルドが失敗しても Android Studio はコンテキストを認識します。このコンテキストは、Studio IDE がコード補完やその他の有用な提案を提供できるようになるため、Kotlin DSL ファイルを修正する場合に役立ちます。

プラグイン ID を確認する

buildscript {} ブロックはプラグインの Maven 座標com.android.tools.build:gradle:7.4.0 など)を使用してビルド クラスパスにプラグインを追加しますが、plugins {} ブロックは代わりにプラグイン ID を使用します。

ほとんどのプラグインでは、apply plugin を使用してプラグインを適用するときに使用される文字列がプラグイン ID です。たとえば、次のプラグイン ID は Android Gradle プラグインの一部です。

  • com.android.application
  • com.android.library
  • com.android.lint
  • com.android.test

完全なプラグインのリストは、Google の Maven リポジトリで確認できます。

Kotlin プラグインは複数のプラグイン ID で参照できます。名前空間付きプラグイン ID を使用し、次の表に従って省略形から名前空間付きプラグイン ID にリファクタリングすることをおすすめします。

短縮プラグイン ID 名前空間が指定されたプラグイン ID
kotlin org.jetbrains.kotlin.jvm
kotlin-android org.jetbrains.kotlin.android
kotlin-kapt org.jetbrains.kotlin.kapt
kotlin-parcelize org.jetbrains.kotlin.plugin.parcelize

Gradle Plugin PortalMaven Central RepositoryGoogle Maven リポジトリでプラグインを検索することもできます。プラグイン ID の仕組みについて詳しくは、カスタム Gradle プラグインの開発をご覧ください。

リファクタリングを実行する

使用するプラグインの ID がわかったら、次の手順を行います。

  1. buildscript {} ブロックで宣言されているプラグインのリポジトリがまだある場合は、代わりに settings.gradle ファイルに移動します。

  2. 最上位の build.gradle ファイルの plugins {} ブロックにプラグインを追加します。ここでは、プラグインの ID とバージョンを指定する必要があります。プラグインをルート プロジェクトに適用する必要がない場合は、apply false を使用します。

  3. 最上位の build.gradle.kts ファイルから classpath エントリを削除します。

  4. モジュール レベルの build.gradle ファイルの plugins {} ブロックにプラグインを追加して、適用します。バージョンはルート プロジェクトから継承されるため、ここで指定する必要があるのはプラグインの ID のみです。

  5. モジュール レベルの build.gradle ファイルからプラグインの apply plugin 呼び出しを削除します。

たとえば、この設定では buildscript {} ブロックを使用しています。

// Top-level build.gradle file
buildscript {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.4.0")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
        ...
    }
}

// Module-level build.gradle file
apply(plugin: "com.android.application")
apply(plugin: "kotlin-android")

これは、plugins {} ブロックを使用した同等の設定です。

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.4.0' apply false
   id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   id 'org.jetbrains.kotlin.android'
   ...
}

// settings.gradle
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins ブロックを変換する

plugins {} ブロックからのプラグインの適用は、Groovy と Kotlin で似ています。次のコードは、バージョン カタログを使用している場合に、Groovy でプラグインを適用する方法を示しています。

// Top-level build.gradle file
plugins {
   alias libs.plugins.android.application apply false
   ...
}

// Module-level build.gradle file
plugins {
   alias libs.plugins.android.application
   ...
}

Kotlin で同じ処理を行うコードは次のようになります。

// Top-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application) apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application)
   ...
}

次のコードは、バージョン カタログを使用していない場合に、Groovy でプラグインを適用する方法を示しています。

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.3.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   ...
}

Kotlin で同じ処理を行うコードは次のようになります。

// Top-level build.gradle.kts file
plugins {
   id("com.android.application") version "7.3.0" apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   id("com.android.application")
   ...
}

plugins {} ブロックの詳細については、Gradle ドキュメントのプラグインの適用をご覧ください。

その他

その他の機能の Kotlin コードサンプルについては、以下のドキュメント ページをご覧ください。

既知の問題

現時点での既知の問題は、Kotlin の方が Groovy よりもビルド速度が遅くなる可能性があることです。

問題を報告する方法

問題の優先順位の判断に必要な情報を提供する方法については、ビルドツールと Gradle バグの詳細をご覧ください。その後、Google の公開 Issue Tracker を使用してバグを報告します。

その他のリソース

Kotlin で記述された Gradle ビルドファイルの実際の例については、GitHub の Now In Android サンプルアプリをご覧ください。