Building an Android Project with Kotlin DSL

Keywords: Gradle Android Junit Google

Preface

Android supports using Kotlin DSL to build Gradle scripts, don't you want to learn a wave yet?

Theme of this article:

1. How to replace Groovy with Kotlin DSL

2. Problems encountered in the process and Solutions

Why use Kotlin DSL

Advantages of using Kotlin DSL:

  • Since Kotlin is now the official Android recommended language, building Gradle scripts with Kotlin is conducive to the unification of the entire project development language and does not require additional learning of Groovy's grammar.
  • Kotlin DSL supports jumping to source
  • Kotlin DSL checks for errors at compile time
  • Kotlin DSL supports code completion and syntax highlighting

Disadvantages of Kotlin DSL:

  • Compile slower than Groovy

Migrating from Groovy to Kotlin DSL

Gradle version: 3.5.3

gradle-wrapper version: 5.6.4

Create a new Android project

Let's take a new Android project as an example and move from groovy to Kotlin DSL step by step

Step 1: Modify the setting.gradle file

Rename setting.gradle to setting.gradle.kts

All Kotlin DSL files are suffixed with.kts file name

Then modify the contents of the file:

include (":app")

rootProject.buildFileName = "build.gradle.kts"

The simple thing to do here is to change the original':'to'()', which is also one of the syntax differences between Kotlin DSL and Groovy.

Step 2: Modify the build.gradle file for Project s

Rename build.gradle to build.gradle.kts

Then modify the content:

buildscript {
    val kotlin_version = "1.3.61" // #1
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.0.0-beta01")  // #2
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

tasks.register("clean", Delete::class) {  // #3
    delete(rootProject.buildDir)
}

The main modification here is three points, which I have identified in the code:

  • ext to val, value is the key to Kotlin's immutable variable
  • Change single quotation mark to double quotation mark for classpath
  • task also needs to change to Kotlin's syntax

Step 3: Modify App's build.gradle file

Similarly, first rename build.gradle to build.gardle.kts

There are a lot of changes that need to be made here, just go straight to the modified code:

plugins {  // #1
    id("com.android.application")
    kotlin("android")
    kotlin("android.extensions")
}

android {
    compileSdkVersion(29)  // #2
    buildToolsVersion("29.0.3")

    defaultConfig {
        applicationId = "com.bluelzy.kotlindsldemo"
        minSdkVersion(21)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        getByName("release") {   // #3
            isMinifyEnabled = false
            proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

dependencies {
    implementation(
        fileTree(  // #4
            mapOf(
                "dir" to "libs", "include" to listOf("*.jar")

            )
        )
    )
    implementation (kotlin(
        "stdlib-jdk7",
        org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION
    ))
    implementation("androidx.core:core-ktx:1.2.0")
    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.constraintlayout:constraintlayout:1.1.3")
    testImplementation("junit:junit:4.12")
    androidTestImplementation("androidx.test.ext:junit:1.1.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")

}

Notes are also identified in the note:

  • apply needs to be changed to plugins
  • Originally: the writing system is replaced by () or=, which is kotlin's setter syntax
  • Notice the changes in buildTypes and fileTree

After completing these steps, we can click on the sync project, which should have been successful if not expected. So far we have actually successfully migrated from Groovy to Kotlin DSL.But did you find that all of our version numbers, dependent versions, TargetSDK, and so on, are written directly in the build.gradle.kts file. Can you manage these variables in one place?Especially when there are multiple modules, we want all the dependencies to be synchronized as long as we change one place.

The official solution is to use buildSrc

Step 4: Create the buildSrc folder

Create a buildSrc folder in the root directory, at the same level as the app folder.The result should be as follows:

You can ignore the three files in the Kotlin folder first.Simply create the src/main/kotlin and build.gradle.kts files.

The next step is to modify the build.gradle.kts file:

plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}

Explain what this buildSrc folder does?

It is officially recommended that we use this folder to manage dependencies for the entire project, that is, we can define multiple dependency-related classes in this drive.

Create Dependencies.kt file

object Apps {
    const val compileSdk = 29
    const val minSdk = 21
    const val targetSdk = 29
    const val versionCode = 1
    const val versionName = "1.0.0"
}

object Versions {
    const val gradle = "3.5.3"
    const val kotlin = "1.3.61"
    const val appcompat = "1.0.2"
    
    /* test */
    const val junit = "4.12"
}

object Libs {
    const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
    const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
}

object TestLibs {
    const val junit = "junit:junit:${Versions.junit}"
}

For example, in this kt file we define three singletons for storing App-related version numbers, dependent version numbers, and dependent package names

Then we can use these defined constants in App build.gradle.kts

Updated build.gradle.kts:

// Omit Code
android {
    compileSdkVersion(Apps.compileSdk)

    defaultConfig {
        applicationId = "com.bluelzy.kotlindsldemo"
        minSdkVersion(Apps.minSdk)
        targetSdkVersion(Apps.targetSdk)
        versionCode = Apps.versionCode
        versionName = Apps.versionName
    }
	// Omit Code
}

dependencies {

    // android supports
    implementation(Libs.appcompat)

    // test
    testImplementation(TestLibs.junit)
}

The above files are not complete. You can add Dependencies.kt files and update build.gradle.kts files by yourself, depending on what you have in your project.

If your project has multiple Modlue s and dependencies are complex, you can define several more kt files in the buildSrc/src/main/kotlin directory to manage different dependencies.It doesn't expand here.

summary

In fact, the simple step to replace Groovy with Kotlin DSL is to rename three gradle-related files to.kts, modify them with Kotlin's syntax, and create dependent kt files in the buildSrc directory.

However, there are also some problems encountered during the process, such as my personal problems.

1. The project can be built successfully or run normally, but the android tags and implementation s in the App build.gradle.kts file have been reporting errors, restarting AS, cleaning the project, and clearing the cache have not solved the problem.

If this happens, you can try to modify the gradle version, which was used in the project I started with:

gradle: 4.0.0-beta01
gradle-wrapper: https://services.gradle.org/distributions/gradle-6.1.1-all.zip

Maybe it's a new version of Bug. I can't find android anyway
Later, I downgraded gradle to:

Gradle version: 3.5.3

gradle-wrapper version: 5.6.4

Then you're ready

2. Errors will occur when modifying the build.gradle.kts file. At this time, you can open the Gradle panel, find the build setup option inside, and run init

Is it clearer than before to attach a screenshot of the build.gradle.kts file using Kotlin DSL?

Reference resources

55 original articles published. 37% praised. 140,000 visits+
Private letter follow

Posted by shubham.amola on Mon, 09 Mar 2020 18:10:09 -0700