skydoves님의 Pokedex 프로젝트를 공부하던 중, Version Catalog
라는 방법에 대해 알게 되었습니다. 저는 지금까지 Groovy 기반의 gradle 파일들로 라이브러리를 선언하고, project 단위의 gradle에서 각 라이브러리의 버전을 관리했었는데 Groovy 기반이 아니라 Kotlin 파일로 gradle을 관리할 수 있다는 것을 알게 되었습니다.
Android Developer 공식사이트에서도 Groovy -> KTS로 migration하는 방법을 소개하고 있습니다.
그렇게 더 공부하다가 알게 된 것이 Kotlin DSL입니다.
Myungpyo Shim님의 포스팅을 참고했습니다.
DSL은 Domain Specific Language
의 약자이며, 반대 의미로는 GPL Global Purpose Language
가 있습니다.
특정 도메인에 국한되어 사용되는 언어라는 의미이며, Kotlin이 이런 DSL에 해당합니다. 앱을 개발하면서 프레임워크나 라이브러리를 사용할 때, 제공되는 언어를 사용하게 되는데 이때의 언어가 DSL입니다.
그럼 기존의 방식이 아니라 kts 파일로 gradle을 관리할 때의 장점은 무엇일까요?
사용해 본 후 제가 느낀 편한 점들입니다.
개발환경
Android Studio : Dolphin
Gradle JDK : Android Strudio default JDK - 11.0.13
Gradle Plugin : 7.5.1
Project Files
로 변경합니다.build.gradle.kts
파일을 생성합니다.import org.gradle.kotlin.dsl.`kotlin-dsl`
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
src/main/java
로 설정합니다.위의 단계를 마친 후, 프로젝트 패널을 Android로 변경하면 아래와 같은 모습이 됩니다.
Project Files
로 패널을 바꾸어 준 후, 5번에서 생성한 java 폴더 안에 자신의 앱 패키지와 동일하게 폴더를 생성해주고 Configuration object와 Dependencies kotlin파일을 생성합니다. (아래 그림을 참고해주세요.)package com.idiot.e_state_twin_android
object Versions {
...
const val kotlin = "1.7.10"
const val agp = "7.2.1"
const val ksp = "1.7.10-1.0.6"
const val hilt = "2.42"
const val jvmTarget = "1.8"
const val material = "1.8.0-alpha01"
const val sceneView = "0.9.0"
const val appcompat = "1.5.0"
const val androidxCore = "1.8.0"
const val androidxFragment = "1.5.0"
const val constraintLayout = "2.1.4"
const val androidxNavigation = "2.5.0"
const val androidxLifecycle = "2.5.0"
const val androidxWork = "2.7.1"
const val androidxRoom = "2.4.3"
const val datastore = "1.0.0"
...
}
object Libraries {
...
const val agp = "com.android.tools.build:gradle:${Versions.agp}"
const val ksp = "com.google.devtools.ksp:symbol-processing-api:${Versions.ksp}"
const val kotlin_gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
const val kotlin_serialization = "org.jetbrains.kotlin:kotlin-serialization:${Versions.kotlin}"
const val navigation_safeargsPlugin = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.androidxNavigation}"
const val hilt_plugin = "com.google.dagger:hilt-android-gradle-plugin:${Versions.hilt}"
const val material = "com.google.android.material:material:${Versions.material}"
const val gson = "com.google.code.gson"
const val sceneview = "io.github.sceneview:arsceneview:${Versions.sceneView}"
const val google_service_auth = "com.google.android.gms:play-services-auth:${Versions.gms}"
const val hilt_android = "com.google.dagger:hilt-android:${Versions.hilt}"
const val hilt_compiler = "com.google.dagger:hilt-android-compiler:${Versions.hilt}"
const val androidx_core = "androidx.core:core-ktx:${Versions.androidxCore}"
...
}
위의 과정까지 마무리하셨다면 이제 gradle 파일에 방금까지 작성한 소스를 사용하시면 됩니다.
import com.idiot.e_state_twin_android.Libraries
import com.idiot.e_state_twin_android.Configuration
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-parcelize")
id("androidx.navigation.safeargs.kotlin")
id("kotlin-kapt")
id("dagger.hilt.android.plugin")
}
android {
compileSdk = Configuration.compileSdk
defaultConfig {
applicationId = "com.idiot.e_state_twin_android"
minSdk = Configuration.minSdk
targetSdk = Configuration.targetSdk
versionCode = Configuration.versionCode
versionName = Configuration.versionName
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildFeatures {
dataBinding = true
viewBinding = true
}
buildTypes {
getByName("debug") {
sourceSets {
getByName("main") {
java.srcDir(File("build/generated/ksp/debug/kotlin"))
}
}
}
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
sourceSets {
getByName("main") {
java.srcDir(File("build/generated/ksp/release/kotlin"))
}
}
}
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(Libraries.hilt_android)
kapt(Libraries.hilt_compiler)
implementation(Libraries.timber)
implementation(project(":utils"))
// FEATURE
implementation(project(":login"))
testImplementation(Libraries.junit)
androidTestImplementation(Libraries.androidx_junit)
androidTestImplementation(Libraries.androidx_espresso)
}