An overview of the
As is known to all, we use Gradle to compile in Android Studio. Gradle is a building tool based on Groovy language. The syntax structure in Gradle that we often see in Build. Gradle is actually the DSL function provided by Groovy.
A DSL is a Domain Specific Language (DSL). It is a special ability that programming languages give developers to write code that appears to be detached from its original syntax structure, thus building a proprietary syntax structure.
There is no doubt that Kotlin supports DSL, and Gradle supports writing Gradle build scripts in Kotlin. Gradle website also provides guidance for migrating Kotlin in Groovy.
Let’s create a new project to transform Gradle files from 0 to one written by Kotlin.
Gradle script modification
For an Android project built on Gradle, the configuration file of Gradle usually consists of the following:
- setting.gradle
- app/build.gradle
- project/build.gradle
So our transformation is nothing more than the transformation of these several documents.
Modified Settings. Gradle
The main function of this file is to be responsible for the declaration of modules in our project. Let’s take a look at its original code, as follows:
include ':app'
rootProject.name = "KotlinGradleDSL"
Copy the code
This code is very simple, which is to declare the main Module of app and define the name of our project. We can rewrite it by using the syntax of Kotlin. Before rewriting, we first change the name of the file to Settings.gradle.kts.
include("app")
rootProject.name = "KotlinGradleDSL"
rootProject.buildFileName = "build.gradle.kts"
Copy the code
Renovation project/build. Gradle
Again, we need to change the name of build.gradle to build.gradle.kts. Let’s take a look at the original code, as follows:
buildscript {
ext.kotlin_version = "1.4.31"
repositories {
google()
jcenter()
}
dependencies {
classpath "Com. Android. Tools. Build: gradle: 4.1.2." "
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Copy the code
The modified code is as follows:
buildscript {
val gradle_version = 4.1.3 ""
val kotlin_version = "1.4.31"
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:$gradle_version")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
allprojects {
repositories {
google()
jcenter()
}
}
tasks {
val clean by registering(Delete::class) {
delete(buildDir)
}
}
Copy the code
In Groovy, we have an extension to Ext, which we don’t have in Kotlin, so we have to declare a local variable ourselves, which we import through string templates, and global dependencies introduced by classpath, which we enclose in curly braces. There is also a clean task, which also needs rewriting.
Next, let’s rewrite the app/build.gradle with the most content.
Modified app/build. Gradle
App /build.gradle contains a lot of content. Let’s look at how each module should be modified.
Plug-in introduction modification
The plugin for Groovy syntax is introduced as follows:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
Copy the code
Using Kotlin, it can be modified as follows:
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")}Copy the code
The introduction of the SDK
The SDK for Groovy syntax is introduced as follows:
compileSdkVersion 30
buildToolsVersion "30.0.3"
Copy the code
Using Kotlin, it can be modified as follows:
compileSdkVersion(30)
buildToolsVersion("30.0.3")
Copy the code
Default configuration modification
The default configuration of Groovy syntax looks like this:
defaultConfig {
applicationId "com.example.kotlingradledsl"
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Copy the code
Using Kotlin, it can be modified as follows:
defaultConfig {
applicationId = "com.example.kotlingradledsl"
minSdkVersion(23)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
Copy the code
Compile type modification
The compilation type of Groovy syntax looks like this:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile ('proguard-android-optimize.txt'), 'proguard-rules.pro'}}Copy the code
Using Kotlin, it can be modified as follows:
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")}}Copy the code
Specify JDK modifications
The specified JDK for Groovy syntax looks like this:
compileOptions {
sourceCompatibility JavaVersion . VERSION_1_8
targetCompatibility JavaVersion . VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
Copy the code
Using Kotlin, it can be modified as follows:
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
Copy the code
Dependent modification
The dependencies of Groovy syntax are as follows:
dependencies {
implementation "Org. Jetbrains. Kotlin: kotlin - stdlib: 1.4.31"
implementation 'androidx. Core: the core - KTX: 1.2.0'
implementation 'androidx. Appcompat: appcompat: 1.1.0'
implementation 'com. Google. Android. Material: material: 1.1.0'
implementation 'androidx. Constraintlayout: constraintlayout: 1.1.3'
}
Copy the code
Using Kotlin, it can be modified as follows:
dependencies {
implementation("Org. Jetbrains. Kotlin: kotlin - stdlib: 1.4.31")
implementation("Androidx. Core: the core - KTX: 1.2.0")
implementation("Androidx. Appcompat: appcompat: 1.1.0." ")
implementation("Com. Google. Android. Material: material: 1.1.0." ")
implementation("Androidx. Constraintlayout: constraintlayout: 1.1.3.")}Copy the code
Complete code display
So far, we have changed all the contents of the automatically generated app/build.gradle. Let’s take a look at the complete code, as shown below:
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android {
compileSdkVersion(30)
buildToolsVersion("30.0.3")
defaultConfig {
applicationId = "com.example.kotlingradledsl"
minSdkVersion(23)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("Org. Jetbrains. Kotlin: kotlin - stdlib: 1.4.31")
implementation("Androidx. Core: the core - KTX: 1.2.0")
implementation("Androidx. Appcompat: appcompat: 1.1.0." ")
implementation("Com. Google. Android. Material: material: 1.1.0." ")
implementation("Androidx. Constraintlayout: constraintlayout: 1.1.3.")}Copy the code
Add more advanced features to app/build.gradle
The content in the above app/build.gradle is the most basic, we still need to add some more advanced features, such as automatic packaging, output APK name modification, etc. On the basis of the above app/build.gradle, let’s start to improve.
Automatic packaging
To implement automatic packaging, we need to create a new signature file. After we have the signature file, we need to configure it in app/build.gradle.
// Configure the signature
signingConfigs {
release {
/ / alias
keyAlias 'zjgsu'
// Alias password
keyPassword '123456'
/ / path
storeFile file('.. /app/src/main/jks/kotlindsl.jks')
/ / password
storePassword '123456'}}Copy the code
Then in the compile type, the release type can be referenced, as shown below:
signingConfig signingConfigs.release
Copy the code
Using Kotlin, it can be modified as follows:
// The signature type
signingConfigs {
register("release") {
/ / alias
keyAlias = "zjgsu"
// Alias password
keyPassword = "123456"
/ / path
storeFile = file("src/main/jks/kotlindsl.jks")
// Sign the file password
storePassword = "123456"}}Copy the code
Then in the compile type, the release type can be referenced, as shown below:
signingConfig = signingConfigs.getByName("release")
Copy the code
After configuring the signature, you can package the APK directly using the command or using the tools provided by Android Studio, as shown below:
Double click assemble to assemble apK. The resulting APK looks like this:
Output Type Configuration
App-debug and app-release are the apK we need, but the name is definitely not what we need, so we need to configure the output type in app/build.gradle, otherwise we have to manually change the name every time we package apK, which is too troublesome. Let’s first take a look at how Groovy syntax is configured, as follows:
// Output type configuration
android.applicationVariants.all { variant ->
def buildType = variant.buildType.name
def fileName
variant.outputs.each {
if (buildType == "release") {
fileName = "APP_NAMEV-${defaultConfig.versionName}.apk"
} else if (buildType == "debug") {
fileName = "APP_NAMEV-${defaultConfig.versionName}_${buildType}.apk"
}
it.outputFileName = fileName
}
}
Copy the code
Using Kotlin, it can be modified as follows:
// Output type
android.applicationVariants.all {
// Compile type
val buildType = this.buildType.name
outputs.all {
// Check whether the output type is APK
if (this is com.android.build.gradle.internal.api.ApkVariantOutputImpl) {
this.outputFileName = "KOTLIN_DSL_V${defaultConfig.versionName}_$buildType.apk"}}}Copy the code
Assemble to assemble apK. The resulting APK looks like this:
Use buildSrc to centrally manage Gradle dependency versions
In Groovy, we often extract build_config.gradle as a global variable control. In Kotlin, we need to use buildSrc to manage gradle dependency versions. Interested can see the introduction of the official website.
To see how this works, we first need to create a buildSrc folder in the root directory, and then create a series of directories, as shown below:
Once the directory is created, you need to write settings.gradle.kts, as follows:
rootProject.buildFileName = "build.gradle.kts"
Copy the code
After writing settings.gradle. KTS, write build.gradle. KTS as follows:
apply {
plugin("kotlin")
}
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath(kotlin("gradle-plugin"."1.4.31"))
}
}
dependencies {
implementation(gradleKotlinDsl())
implementation(kotlin("stdlib"."1.4.31"))
}
repositories {
gradlePluginPortal()
}
Copy the code
After compiling, we can write the kotlinConstants.kt public class as follows:
// Global constants
object KotlinConstants {
/ / Gradle version
const val gradle_version = 4.1.3 ""
/ / Kotlin version
const val kotlin_version = "1.4.31"
}
// Apply the configuration
object AppConfig {
// Dependent version
const val compileSdkVersion = 30
// Compile the tool version
const val buildToolsVersion = "30.0.3"
/ / package name
const val applicationId = "com.example.kotlingradledsl"
// Minimum support for SDK
const val minSdkVersion = 23
// Currently based on the SDK
const val targetSdkVersion = 30
// Version encoding
const val versionCode = 1
// Version name
const val versionName = "1.0"
}
// Dependency configuration
object DependenciesConfig {
/ / Kotlin based library
const val STD_LIB = "org.jetbrains.kotlin:kotlin-stdlib:${KotlinConstants.kotlin_version}"
}
Copy the code
With the kotlinconstants.kt we can use it in.gradle files like app/build.gradle.kts code as follows:
// Reference the plug-in
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")}/ / Android attributes
android {
compileSdkVersion(AppConfig.compileSdkVersion)
buildToolsVersion(AppConfig.buildToolsVersion)
defaultConfig {
applicationId = AppConfig.applicationId
minSdkVersion(AppConfig.minSdkVersion)
targetSdkVersion(AppConfig.targetSdkVersion)
versionCode = AppConfig.versionCode
versionName = AppConfig.versionName
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// The signature type
signingConfigs {
register("release") {
/ / alias
keyAlias = "zjgsu"
// Alias password
keyPassword = "123456"
/ / path
storeFile = file("src/main/jks/kotlindsl.jks")
// Sign the file password
storePassword = "123456"}}// Compile type
buildTypes {
getByName("release") {
isMinifyEnabled = false
// Automatic signature package
signingConfig = signingConfigs.getByName("release")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")}}// Output type
android.applicationVariants.all {
// Compile type
val buildType = this.buildType.name
outputs.all {
// Check whether the output type is APK
if (this is com.android.build.gradle.internal.api.ApkVariantOutputImpl) {
this.outputFileName = "KOTLIN_DSL_V${defaultConfig.versionName}_$buildType.apk"}}}/ / specify JDK
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(DependenciesConfig.STD_LIB)
implementation("Androidx. Core: the core - KTX: 1.2.0")
implementation("Androidx. Appcompat: appcompat: 1.2.0")
implementation("Com. Google. Android. Material: material: 1.3.0")
implementation("Androidx. Constraintlayout: constraintlayout: 2.0.4.")}Copy the code
At this point, we are done with Gradle Kotlin DSL.
The source code
The source code has been uploaded to Github, as needed.