Groovy에서 Kotlin으로 빌드 구성 이전

Android Gradle 플러그인 4.0에는 Gradle 구성 파일에 전통적으로 사용되는 프로그래밍 언어인 Groovy를 대체하기 위해 Gradle 빌드 구성에서 Kotlin을 사용할 수 있는 지원이 추가되었습니다.

Gradle 스크립트를 작성할 때 Groovy보다 Kotlin이 선호됩니다. Kotlin이 더 읽기 쉽고 더 나은 컴파일 시간 확인과 IDE 지원을 제공하기 때문입니다.

Kotlin은 현재 Groovy에 비해 Android 스튜디오의 코드 편집기에서 더 나은 통합을 제공하지만 Kotlin을 사용하는 빌드는 Groovy를 사용하는 빌드보다 느린 경향이 있으므로 이전 여부를 결정할 때는 빌드 성능을 고려하세요.

이 페이지에서는 Android 앱의 Gradle 빌드 파일을 Groovy에서 Kotlin으로 변환하는 방법에 관한 기본 정보를 제공합니다. 자세한 이전 가이드는 Gradle의 공식 문서를 참고하세요.

타임라인

Android 스튜디오 Giraffe부터 새 프로젝트는 빌드 구성에 기본적으로 Kotlin DSL(build.gradle.kts)을 사용합니다. 이는 Groovy DSL (build.gradle)보다 구문 강조, 코드 완성, 선언 탐색 기능 등을 갖춘 더 나은 편집 환경을 제공합니다. 자세한 내용은 Gradle Kotlin DSL 기본 지침서를 참고하세요.

일반적인 용어

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이 아닌 project에서 toString()을 호출합니다. 루트 디렉터리의 값을 가져오려면 ${project.rootDir} 표현식을 중괄호로 묶습니다.

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

    자세한 내용은 Kotlin 문서의 문자열 템플릿을 참고하세요.

파일 확장자 이름 바꾸기

콘텐츠를 이전할 때 각 빌드 파일에 .kts를 추가합니다. 예를 들어 settings.gradle 파일과 같은 빌드 파일을 선택합니다. 파일 이름을 settings.gradle.kts로 바꾸고 파일 콘텐츠를 Kotlin으로 변환합니다. 각 빌드 파일을 이전한 후에도 프로젝트가 여전히 컴파일되는지 확인합니다.

가장 작은 파일을 먼저 이전하여 경험을 쌓은 후 계속 진행하세요. 프로젝트에서 Kotlin 빌드 파일과 Groovy 빌드 파일을 함께 사용할 수 있으므로 서두르지 말고 신중하게 이전하세요.

defval 또는 var로 바꾸기

defKotlin에서 변수를 정의하는 방법val 또는 var로 바꿉니다. 다음은 Groovy에서의 변수 선언입니다.

def building64Bit = false

다음은 Kotlin으로 작성된 동일한 코드입니다.

val building64Bit = false

불리언 속성 앞에 is 추가

Groovy는 속성 이름을 기반으로 속성 추론 로직을 사용합니다. 불리언 속성 foo의 경우 추론된 메서드getFoo 또는 setFoo, isFoo일 수 있습니다. 따라서 Kotlin으로 변환되면 속성 이름을 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에서는 디버그 빌드 유형과 출시 빌드 유형만 암시적으로 사용할 수 있습니다. 다른 모든 맞춤 빌드 유형은 수동으로 만들어야 합니다.

Groovy에서는 먼저 만들지 않고도 디버그 빌드 유형과 출시 빌드 유형, 기타 특정 빌드 유형을 사용할 수 있습니다. 다음 코드 스니펫은 Groovy에서 debug, release, benchmark 빌드 유형이 있는 구성을 보여줍니다.

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

Kotlin에서 동일한 구성을 만들려면 benchmark 빌드 유형을 명시적으로 만들어야 합니다.

buildTypes {
 debug {
   ...
 }

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

buildscript에서 plugins 블록으로 이전

빌드가 buildscript {} 블록을 사용하여 프로젝트에 플러그인을 추가하는 경우 plugins {} 블록을 대신 사용하도록 리팩터링해야 합니다. plugins {} 블록을 사용하면 플러그인을 더 쉽게 적용할 수 있으며 버전 카탈로그와 잘 호환됩니다.

또한 빌드 파일에서 plugins {} 블록을 사용하면 Android 스튜디오는 빌드가 실패하더라도 컨텍스트를 인식합니다. 이 컨텍스트는 스튜디오 IDE에서 코드 완성을 실행하고 기타 유용한 제안을 제공할 수 있으므로 Kotlin DSL 파일을 수정하는 데 도움이 됩니다.

플러그인 ID 찾기

buildscript {} 블록은 플러그인의 Maven 좌표(예: com.android.tools.build:gradle:7.4.0)를 사용하여 빌드 클래스 경로에 플러그인을 추가하지만 plugins {} 블록은 대신 플러그인 ID를 사용합니다.

대부분의 플러그인에서 플러그인 ID는 apply plugin를 사용하여 플러그인을 적용할 때 사용되는 문자열입니다. 예를 들어 다음 플러그인 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 플러그인 포털, Maven 중앙 저장소, Google 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 {} 블록에서 플러그인을 적용하는 것은 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 샘플 앱을 참고하세요.