使用Kotlin DSL構建Android項目

前言

Android支持使用Kotlin DSL來構建Gradle腳本了,還不趕緊學習一波?

本文主題:

1.如何使用Kotlin DSL替換Groovy

2.過程中遇到的問題以及解決方法

爲什麼要使用Kotlin DSL

使用Kotlin DSL 的優勢:

  • 由於現在Kotlin是Android官方推薦語言,因此使用Kotlin構建Gradle腳本有利於整個項目開發語言的統一,不需要另外學習Groovy的語法
  • Kotlin DSL 支持跳轉到源碼
  • Kotlin DSL 在編譯時檢查錯誤
  • Kotlin DSL 支持代碼自動補全和語法高亮

Kotlin DSL的劣勢:

  • 編譯速度比Groovy慢

從Groovy遷移到Kotlin DSL

Gradle 版本: 3.5.3

gradle-wrapper版本:5.6.4

新建一個Android項目

我們以一個新的Android項目爲例,一步步從groovy遷移到Kotlin DSL

第一步:修改setting.gradle文件

setting.gradle 重命名爲 setting.gradle.kts

所有的Kotlin DSL 文件,都是以.kts 爲文件名後綴

然後修改文件裏面的內容:

include (":app")

rootProject.buildFileName = "build.gradle.kts"

這裏做的事情也很簡單,就是把原本的 “:” 改成了 “()” 這也是Kotlin DSL和Groovy語法的差別之一。

第二步:修改Project的build.gradle文件

build.gradle 重命名爲 build.gradle.kts

然後修改內容:

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)
}

這裏主要修改的就是三點,我已經在代碼中標識出來了:

  • ext改成 val,val是Kotlin不可變變量的關鍵字
  • classpath 的 單引號 改爲 雙引號
  • task 同樣需要改成 Kotlin 的語法

第三步:修改App的build.gradle文件

同樣的,首先把build.gradle重命名爲 build.gardle.kts

這裏需要做的變動就比較多了,直接上修改後的代碼:

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")

}

需要注意的地方同樣在註釋中標識出來了:

  • apply 需要改成 plugins
  • 原本 : 的寫法統統換成 () 或者 =,這是kotlin的setter語法
  • 注意buildTypes和fileTree的變化

完成了這幾步之後,我們就可以點擊sync project,如無意外的話應該是可以成功的,到目前爲止其實我們就已經從Groovy成功遷移到了Kotlin DSL了。但是大家有沒有發現一個問題,就是現在我們所有的版本號,依賴版本,TargetSDK等等,都是直接寫在build.gradle.kts文件中的,能不能把這些變量都統一放到一個地方管理呢?特別是多個Module的時候,我們希望只要改動一個地方,所有的依賴都能夠同步。

其實官方已經給我們提供了一個解決方案了,那就是使用buildSrc

第四步:創建buildSrc文件夾

在根目錄下創建一個buildSrc文件夾,也就是和app文件夾同一等級。創建後的結果應該是這樣的:

在這裏插入圖片描述

大家可以先忽略Kotlin文件夾裏面的3個文件。只要創建了src/main/kotlin 以及 build.gradle.kts 文件就可以了。

接下來就要修改build.gradle.kts文件了:

plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}

解釋一下,這一個buildSrc文件夾的作用是什麼呢?

官方推薦我們使用這個文件夾來管理整個項目的依賴,也就是說,我們可以在這個路勁定義多個和依賴相關的類。

創建Dependencies.kt文件

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}"
}

舉個例子,我們在這個kt文件中定義了三個單例,分別用於存放App相關的版本號,依賴相關的版本號,以及依賴包的名稱

然後我們就可以在App的build.gradle.kts裏面用上這些定義的常量了

更新後的build.gradle.kts:

// 省略代碼
android {
    compileSdkVersion(Apps.compileSdk)

    defaultConfig {
        applicationId = "com.bluelzy.kotlindsldemo"
        minSdkVersion(Apps.minSdk)
        targetSdkVersion(Apps.targetSdk)
        versionCode = Apps.versionCode
        versionName = Apps.versionName
    }
	// 省略代碼
}

dependencies {

    // android supports
    implementation(Libs.appcompat)

    // test
    testImplementation(TestLibs.junit)
}

上面的文件並不是完整的,大家可以自己按照項目裏的依賴添加到Dependencies.kt文件,以及更新build.gradle.kts文件即可。

如果項目有多個Modlue,而且依賴關係也很複雜,那麼我們可以在buildSrc/src/main/kotlin 目錄下多定義幾個kt文件,用於管理不同的依賴。這裏就不展開了。

總結

其實使用Kotlin DSL來替代Groovy的步驟比較簡單,就是把3個gradle相關的文件重命名爲.kts,然後用Kotlin的語法修改,最後在buildSrc目錄下創建依賴相關的kt文件。

但是在這個過程中同樣會遇到一些問題,以我個人遇到的問題爲例

1.項目能build成功,也可以正常運行,但是在App的build.gradle.kts文件中 android 標籤和 implementation 一直報錯,重啓AS,clean project,還有清除緩存都無法解決問題。

如果出現這個問題的話,大家可以嘗試修改gradle的版本,我一開始創建的項目使用的gradle版本是:

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

可能是新版本的Bug,怎麼都找不到android
後面我就把gradle降級爲:

Gradle 版本: 3.5.3

gradle-wrapper版本:5.6.4

然後就可以了

2.在修改build.gradle.kts文件的過程中會報錯,這個時候大家可以打開Gradle面板,找到裏面的build setup選項,運行init

最後附上一張使用了Kotlin DSL的build.gradle.kts文件截圖,是不是比之前清晰多了呢?

在這裏插入圖片描述

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章