Now that we've migrated our build.gradle files to make use of the Kotlin Gradle DSL, let's improve the way in which we define dependencies and build constants. More specifically, we are going to use Kotlin object declarations to define our dependencies so they can be defined once and reused elsewhere. To do this, perform the following steps:
- To start, create a new directory named buildSrc within the root project directory:
- Next, we're going to create the following two files within the buildSrc directory:
- buildSrc/build.gradle.kts
- buildSrc/src/main/kotlin/Dependencies.kt
This buildSrc directory is a special directory in which we can create constants and objects that Gradle will make available to us during the configuration and building of our project. To make this work, we first need to update buildSrc/build.gradle.kts with the following code:
repositories { jcenter() }
plugins {
'kotlin-dsl'
}
By applying the 'kotlin-dsl' plugin, Gradle will use the objects and constants defined in this directory.
- Now we can define some constants to use within our build. We'll define this within the newly created buildSrc/src/main/kotlin/Dependencies.kt file. To start, we'll define a String constant for the current version of Kotlin:
object Deps {
object Kotlin {
const val version = "1.3.31"
}
}
Because we're working with a simple Kotlin file, we can define our constants as top-level properties or within an object declaration, as in the previous code snippet.
- Once the constant is defined, we can make use of it from our other Gradle files like this:
// root/build.gradle.kts
buildscript {
extensions.add("kotlin_version", Deps.Kotlin.version)
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.5.0-beta04")
classpath ("org.jetbrains.kotlin:kotlin-gradle-
plugin:${Deps.Kotlin.version}")
}
}
We can access the defined constant as if it were any other type of Kotlin code that was referencing it. This approach can be used for more than just constants. We can define all of our dependencies within the buildSrc directory so they can be reused elsewhere in a consistent manner. Let's examine how this works:
- Let's start by updating Dependencies.kt with some additional dependency constants, as follows:
object Deps {
object Kotlin {
private const val version = "1.3.31"
const val gradlePlugin = "org.jetbrains.kotlin:kotlin-
gradle-plugin:$version"
}
object Android {
object Tools {
const val androidGradle = "com.android.tools.build:
gradle:3.5.0-beta04"
}
}
}
- Now, we can update build.gradle.kts to completely remove any reference to Kotlin version or plugin versions:
// root/build.gradle/kts
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath(Deps.Android.Tools.androidGradle)
classpath (Deps.Kotlin.gradlePlugin)
}
}
This nicely encapsulates the available dependencies and their versions within the buildSrc directory. This makes your dependencies much easier to manage in larger, possibly multi-module, projects. This also makes it easier to navigate to dependencies from our build.gradle.kts files and to refactor dependencies across our project. Let's now move on to the tools used for this.