再见,Groovy! 教你如何使用Kotlin SDL 编写Gradle脚本!

2020/08/05 08:40
阅读数 3.1K

作者:shusheng007, 地址:https://blog.csdn.net/ShuSheng0007/article/details/106763989

概述

通过秒懂Gradle之从完全懵逼到是懂非懂熟悉了gradle,达到了是懂非懂的境地,今天让我们实战演练一下,此演练具有实际意义,如果你愿意完全可以将其用在实际项目中。

Gradle从5.0就已经支持Kotlin DSL1.0了,说明Gadle从5.0开始已经准备好在生产上使用了,何况现在已经发展到6.5了,时机已经很成熟。

Android Studio 4.0 对应的gradle 插件为4.0,对应的Gradle为6.1.1了,所以是时候尝试一下使用kotlin DSL写gradle脚本了。

为什么要用Kotlin DSL写gradle脚本

撇开其他方面,就单从提高程序员生产效率方面就有很多优点:

  • 脚本代码自动补全
  • 跳转查看源码
  • 动态显示注释
  • 支持重构(Refactoring)

怎么样,要是你经历过groovy那令人蛋疼的体验,kotlin会让你爽的起飞,接下来让我们开始吧。

从Groovy到Kotlin

让我们使用Android Studio 新建一个Android项目,AS默认会为我们生成3个gradle脚本文件。

  • settings.gradle (属于 project)
  • build.gradle (属于 project)
  • build.gradle (属于 module)

我们的目的就是转换这3个文件

第一步: 修改groovy语法到严格格式

groovy既支持双引号""也支持单引号'',而kotlin只支持双引号,所以首先将所有的单引号改为双引号

例如 include ':app' -> include ":app"

groovy方法调用可以不使用() 但是kotlin方法调用必须使用(),所以将所有方法调用改为()方式。

例如

implementation "androidx.appcompat:appcompat:1.0.2"

改为

 implementation ("androidx.appcompat:appcompat:1.0.2")

groovy 属性赋值可以不使用=,但是kotlin属性赋值需要使用=,所以将所有属性赋值添加=

例如

applicationId "com.ss007.gradlewithkotlin"

改为

applicationId = "com.ss007.gradlewithkotlin"

完成以上几步,准备工作就完成了。

第二步:修改文件名并转换

由于gradle支持groovykotlin脚本混编,所以我们每转换完一个文件就同步一下,确保没有错误。

  • 1、转换 setting.gradle文件

将文件名加上kts后缀为setting.gradle.kts

然后将内容修改为如下所示(其实完成第一步后就不用做修改了,和groovy一毛一样,)

include(":app")
rootProject.name = "GradleWithKotlinDsl"
  • 2、转换project的 build.gradle文件

将文件名加kts后缀为build.gradle.kts

然后将内容修改为如下所示:

buildscript {
    var kotlinVersion: String by extra
    kotlinVersion="1.3.72"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath ("com.android.tools.build:gradle:4.0.0")
        classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")

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

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

tasks.register<Delete>("clean") {
    delete(rootProject.buildDir)
}

这个文件转换有两个地方需要注意:

第一: buildscript{} 里的ext.kotlin_version'改为 var kotlinVersion: String by extra,关于extension object 这块,kotlin表现的不如groovy优秀,比较啰嗦。第二: task 的申明方式变了

  • 3、转换 modulebuild.gradle文件

这个是我们的重点要转换的了,也最为复杂。首先将文件名加kts后缀为build.gradle.kts

然后修改内容如下:

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

android {
    compileSdkVersion (29)
    buildToolsVersion ("30.0.0")

    defaultConfig {
        applicationId = "top.ss007.gradlewithkotlindsl"
        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 {
    implementation (fileTree(mapOf("dir" to "libs""include" to listOf("*.jar"))))
    implementation ("org.jetbrains.kotlin:kotlin-stdlib:1.3.72")
    implementation ("androidx.core:core-ktx:1.3.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")
}

有3处需要特殊处理

  • 第一:插件的引入方式从 apply plugin到声明式
plugins{
 id(xxx)
  ...
}
  • 第二: buildTypes{} 块里面获取 buildType的方式有变化。

因为buildTypes块里面的类型为NamedDomainObjectCollection<BuildType>``,其不存在名为release的方法。而是通过release这个name可获取到一个BuildType类型的对象。而这个对象里面有一个方法叫setMinifyEnabled(false),写成属性调用方式为isMinifyEnabled = false`。

  • 第三: dependencies{} 块里面编译lib 文件夹中 jar文件的内容有变化
dependencies {
    implementation (fileTree(mapOf("dir" to "libs""include" to listOf("*.jar"))))
 }

我们看一下fileTree那个方法的签名

ConfigurableFileTree fileTree(Map<String, ?> args);

可见其需要一个Map的入参

完成以上几步后同步一下gradle脚本就ok了。

到目前为止一切都工作正常,但是在实际项目中我们经常使用project下的gradle脚本的一个extension object来统一维护版本号,如下所示:

ext{
 // Android config
    androidBuildToolsVersion = "30.0.0"
    ...
}

但是在kotlin里面从其他模块下访问不到project下的extra,所以需要使用buildSrc的方式

使用buildSrc改进维护性

在根目录下创建一个buildSrc目录,当构建时gradle会自动包括此目录下的文件,在所有gradle文件中都是可以访问到这里面的类,我们可以将版本号统一维护在这里。

其文件结构如下:

Config 文件内容如下

object Config {
    object Android {
        const val buildToolsVersion = "30.0.0"
        const val minSdkVersion = 21
        const val targetSdkVersion = 29
        const val compileSdkVersion = 29
        const val applicationId = "top.ss007.gradlewithkotlindsl"
        const val versionCode = 1
        const val versionName = "1.0"
    }

    object AndroidLib{
        const val appcompatVersion= "1.1.0"
        const val constraintLayoutVersion="1.1.3"
    }
    ...
}

然后就可以在gradle文件中引用里面的值了,例如:

defaultConfig {
        applicationId = Config.Android.applicationId
        minSdkVersion (Config.Android.minSdkVersion)
        ...
    }
    
dependencies {
    ...
    implementation ("androidx.appcompat:appcompat:${Config.AndroidLib.appcompatVersion}")
    implementation ("androidx.constraintlayout:constraintlayout:${Config.AndroidLib.constraintLayoutVersion}")

总结

总体来说,Gradle团队已经拥抱Kotlin了,教程也是groovykotlin共存的,相信kotlingradle的使用中会越来越多的,说不定哪天android studio的模板项目就会使用kotlin作为默认gradle脚本的,毕竟kotlin已经是Android开发的首推语言了。

如果要深入了解,可以参考官网相关部分 Gradle Kotlin DSL Primer

本文源码:https://github.com/shusheng007/GradleWithKotlinDsl


---END---


推荐阅读:
强大!ASM插桩实现Android端无埋点性能监控!
10分钟彻底理解Redis的持久化机制:RDB和AOF
这15个Android开源库,只有经常逛Github的才知道!
牛逼!腾讯十大开源项目出炉!
Flutter 混合开发高仿大厂App
支付宝架构到底有多牛逼?看完这篇你就明白了!
Glide实现共享元素无缝转场效果,只需四步!
学会这些 IDEA  Debug调试技巧!提升开发效率10倍!
程序员的重复劳动陷阱
谈谈Android AOP技术方案


更文不易,点个“在看”支持一下👇

本文分享自微信公众号 - 技术最TOP(Tech-Android)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部