Android之Gradle Kotlin DSL

Android Studio Gradle
3.4.2 5.1.1

首先kotlin-dsl不是什麼新鮮的東西了,Gradle5.0發佈的時候就有了 Gradle Kotlin DSL目前的版本是1.0.2html

如今是否能夠拋棄groovy擁抱kotlin了呢,~~遷移仍是有點小麻煩的!android

目前在Android Studio中建立項目時,默認狀況下使用Groovy建立Gradle腳本,那如何向kotlin-dsl遷移呢?git

語法替換

通常狀況下,Groovy中使用單引號或者雙引號來表達字符串。可是Kotlin必須須要雙引號。github

對Gradle腳本(以app目錄下的build.gralde爲例)中的全部單引號執行查找和替換(cmd + R),並將其所有更改成雙引號。 而後挨個開始轉爲kotlin-dsl中的語法bash

apply plugin: "com.android.application"

apply plugin: "kotlin-android"

apply plugin: "kotlin-android-extensions"

複製代碼

轉換以後:(先不用管大量報錯)markdown

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

複製代碼

轉換前:app

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.1"
    defaultConfig {
        applicationId "com.crucio.test"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
        }
    }
}


複製代碼

改成ide

android {
    compileSdkVersion (29)
    buildToolsVersion ("29.0.1")
    defaultConfig {
        applicationId = "com.crucio.test"
        minSdkVersion (21)
        targetSdkVersion (29)
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

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



dependencies {
    val kotlin_version = "1.3.41"
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
    implementation ("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version")
    implementation ("androidx.appcompat:appcompat:1.0.2")
    implementation ("androidx.core:core-ktx:1.0.2")
    implementation ("androidx.constraintlayout:constraintlayout:1.1.3")
    testImplementation ("junit:junit:4.12")
    androidTestImplementation ("androidx.test:runner:1.2.0")
    androidTestImplementation ("androidx.test.espresso:espresso-core:3.2.0")
}

複製代碼

這時候咱們修改build.gradle文件名稱,改成build.gradle.kts 若是語法沒有錯誤會出現以下圖所示: 函數

提示:有新的腳本依賴項可用 這時候點擊 Enable auto-reloadoop

這時候發現遷移成功了。可是kotlin能不能實現相似於groovy ext依賴呢?buildSrc登場~

buildSrc

自動補全+單擊跳轉來了,無需在文件之間手動來回切換~ 先看下官方對buildSrc介紹

  1. 在項目根目錄下新建一個名爲buildSrc的文件夾(與項目裏的app文件夾同級)。

  2. 在buildSrc文件夾裏建立名爲build.gradle.kts的文件

plugins{
    `kotlin-dsl`
}

repositories {
	 // 必不可少
    jcenter()
}
複製代碼
  1. 在buildSrc文件夾裏建立src/main/kotlin文件夾,以下圖所示。並在該文件夾下建立kt文件。

寫完相關依賴代碼後咱們再去build.gradle.kts文件中進行替換

看見沒? 已經能夠自動提示補全了。

buildSrc插件

若是嫌棄手動buildSrc有點麻煩,那插件大法也是有的。

舉例一個 buildSrcVersions 自動生成 buildSrc 目錄不過插件會生成一個空的 settings.gradle.kts 文件,能夠考慮刪掉。

補充

關於自定義構建類型 groovy中咱們自定義構件類型是這樣的

buildTypes {
  release {
    ...
  }
  debug {
    ...
  }
}
複製代碼

可是在kotlin-dsl中buildTypes依賴於NamedDomainObjectContainer

/**
     * Encapsulates all build type configurations for this project.
     *
     * <p>For more information about the properties you can configure in this block, see {@link
     * BuildType}.
     */
    public void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) {
        checkWritability();
        action.execute(buildTypes);
    }
複製代碼

NamedDomainObjectContainer以及父類NamedDomainObjectCollection有幾個用於訪問這些字符串鍵的函數 默認都會有release 與 debug 咱們能夠用getByName,由於構建容器中默認是有映射的

/**
     * Locates an object by name, failing if there is no such object. The given configure action is executed against
     * the object before it is returned from this method.
     *
     * @param name The object name
     * @param configureAction The action to use to configure the object.
     * @return The object with the given name, after the configure action has been applied to it. Never returns null.
     * @throws UnknownDomainObjectException when there is no such object in this collection.
     * @since 3.1
     */
    T getByName(String name, Action<? super T> configureAction) throws UnknownDomainObjectException;

複製代碼

若是想要自定義構件類型,getByName會拋異常,咱們能夠用maybeCreate

/**
     * Looks for an item with the given name, creating and adding it to this container if it does not exist.
     *
     * @param name The name to find or assign to the created object
     * @return The found or created object. Never null.
     */
    T maybeCreate(String name);

複製代碼

結尾

先簡單說這麼多,

附上根目錄的build.gradle.kts

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath(Libs.com_android_tools_build_gradle)
        classpath(Libs.kotlin_gradle_plugin)
    }
}

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

tasks {
    val clean by registering(Delete::class) {
        delete(buildDir)
    }
}


複製代碼
相關文章
相關標籤/搜索