本文主要是介绍Android Gradle开发与应用 (八) :Kotlin DSL,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 前言
本文介绍了Gradle Kotlin DSL
相关的一些知识点
2. DSL是什么
DSL
是为特定领域设计的专门的语言,也就是设计了一门语言,然后解决某个特定的领域的特定问题。
2.1 举例说明
以下的这些都可以称之为DSL
- 正则表达式 :用于文本处理的特定语言
- SQL :用于数据库查询的领域特定语言
- HTML : 用于描述网页结构的领域特定语言
- CSS:用于描述网页样式的领域特定语言
- Android XML布局 : 用于描述Android页面的领域特定语言
而Gradle 中的 Groovy DSL 和 Kotlin DSL 就用来编写Gradle
构建脚本的领域特定语言
像Kotlin它不仅可以做一些Android开发,还可以做后端,它不属于DSL,但是我们可以通过Kotlin的一些语法规则,来开发一些特定领域的DSL语言。
2.2 Kotlin DSL
Kotlin
当中的DSL
,使用高阶函数和一些Lambda表达式配合来进行编写的。
对于DSL
没有明确的语法规定,只要能编写出一门语言,一种语法规则,解决特定领域的问题,那么他就可以称之为DSL
。
Gradle
构建工具现在也使用Kotlin
作为Gradle
的主要编写语言了。
我们去创建Kotlin
的Gradle
的时候,可以发现,它里面的内容和以前的Gradle
没什么区别,但是语言上是用的Kotlin。
其实就是用Kotlin
写了一个专门为Gradle
使用的DSL
。
3. kotlin-dsl是什么
在用Kotlin编写的Gradle插件中,会有kotlin-dsl
这一句
plugins {`java-gradle-plugin``kotlin-dsl`
}
我们点进去可以看到kotlin-dsl
中间的-
不是标准的kotlin
语法,所以要加上``来做区分。
public val val PluginDependenciesSpec.`kotlin-dsl`: PluginDependencySpecget() = id("org.gradle.kotlin.kotlin-dsl") version "2.4.1"
也就是说 kotlin-dsl
就是PluginDependencySpec
的一个扩展属性。
其实就是相当于id("org.gradle.kotlin.kotlin-dsl") version "2.4.1"
所以如果把kotlin-dsl
这行代码改为id("org.gradle.kotlin.kotlin-dsl") version "2.4.1"
,效果是一样的。
可以在Kotlin插件项目里,全局搜索
org.gradle.kotlin.kotlin-dsl
3.1 kotlin-dsl插件的作用
提供Kotlin
编写Gradle
脚本的能力,从而可以替代传统的Groovy语言。
-
使用Kotlin DSL的编程风格,可以使程序更加简单干净、直观简洁。这有助于提升开发效率,降低出错的可能性,并使得构建脚本更易于理解和维护。
-
此外,Kotlin DSL还提供了强大的类型检查和智能代码补全功能,这些功能可以进一步提高开发者的编写体验。同时,由于Kotlin语言的强大功能,Kotlin DSL也支持更复杂的构建逻辑和更灵活的脚本编写方式。
4. groovy和kotlin的语法糖
4.1 apply plugin
4.1.1 groovy中的apply plugin
apply plugin : MyPlugin
等价于
apply([plugin : MyPlugin])
当方法的参数是一个map
的时候,可以将方括号[]
去掉
apply(plugin: MyPlugin)
当不引起歧义的时候,可以把圆括号去掉
apply plugin : MyPlugin
4.1.2 kotlin中的apply plugin
apply(plugin = "com.android.application")
实际上也是个函数调用
public fun org.gradle.api.plugins.PluginAware.apply(from: kotlin.Any? = COMPILED_CODE, plugin: kotlin.String? = COMPILED_CODE, to: kotlin.Any? = COMPILED_CODE): kotlin.Unit { }
4.2 gradle和kotlin中的plugins
4.2.1 groovy中的plugins
plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}
本质是有一个plugins
的方法,调用了一个闭包
实质上是
plugins({id('com.android.application').version('8.1.3').apply(false)
})
4.2.2 kotlin中的plugins
plugins {id("com.android.application") version "8.1.3" apply false
}
本质上也就是一个函数调用
public final fun plugins(block: org.gradle.kotlin.dsl.PluginDependenciesSpecScope.() -> kotlin.Unit): kotlin.Unit { /* compiled code */ }
id
方法会返回一个PluginDependencySpec
,PluginDependencySpec
中有version
和apply
方法
public interface PluginDependencySpec {PluginDependencySpec version(@Nullable String version);default PluginDependencySpec version(Provider<String> version) {return this.version((String)version.get());}PluginDependencySpec apply(boolean apply);
}
4.2.3 apply plugin 和 plugins的区别
- plugins是Gradle较新的方式,用于声明性地应用插件。有更简洁的语法,更好的插件版本控制
- 传统的apply方法机制则更加灵活,可以动态地加载和应用插件
现在一般情况下都用plugins即可,除非是要使用build.gradle
中自己写的gradle插件,采用apply plugin
进行引用。
5. Groovy DSL 和 Kotlin DSL的区别
5.1 gradle中,如下Groovy和Kotlin的写法为什么会有不同 ?
比如下面的这行代码 greeting.message = 'Hi from Gradle'
和 the<GreetingPluginExtension>().message.set("Hi from Gradle")
在 Gradle
中,Groovy DSL
和 Kotlin DSL
提供了不同的语法和风格来配置构建脚本。这两种语言不同的写法来配置插件扩展,是由于这两种 DSL
在语法和设计哲学上的差异造成的。
首先,来看 Groovy DSL
的写法:
greeting.message = 'Hi from Gradle'
在 Groovy DSL
中,插件的扩展对象通常会被添加到项目的 extensions
集合中,并且可以直接通过扩展对象的名称(在这个例子中是 greeting
)来访问。Groovy
语言允许直接对属性进行赋值操作,因此可以非常方便地通过点号 .
操作符来设置属性的值。
接下来,看 Kotlin DSL
的写法:
the<GreetingPluginExtension>().message.set("Hi from Gradle")
在 Kotlin DSL
中,由于 Kotlin
是一种静态类型语言,它提供了更严格的类型检查和更丰富的类型系统。因此,访问插件的扩展对象需要使用 the<T>()
函数,这个函数是 Gradle Kotlin DSL
提供的一个帮助函数,用于获取指定类型的扩展对象。这样做可以提供更好的类型安全,并且使代码更加清晰和易于理解。
另外,set
方法的使用也是 Kotlin 语言特性的体现。在 Kotlin 中,属性默认是不可变的(val),如果需要修改属性的值,通常需要提供一个 set
方法。虽然 Kotlin 也支持可变属性(var),但在 Gradle Kotlin DSL
的上下文中,使用 set
方法可能是为了遵循 Gradle API
的约定,或者是为了强调这是一个设置操作。
总结来说,Groovy DSL
和 Kotlin DSL
在语法和风格上的差异导致了配置插件扩展时的不同写法。Groovy DSL
提供了更加直接和简洁的语法,而 Kotlin DSL
则强调了类型安全和清晰的代码结构。这些差异使得两种 DSL
都有其独特的优点,开发者可以根据个人喜好和项目需求选择使用哪一种。
5.2 gradle中,tasks.register(‘xxx’)和task xxx这两种新建Task方式,有什么区别 ?
在Gradle中,tasks.register('xxx')
和task xxx
这两种方式用于新建Task, 但它们之间存在一些区别:
-
Groovy 和 Kotlin 语法:
task xxx
是 Groovy 语法,它使用 Groovy 闭包来配置任务。tasks.register('xxx')
是 Kotlin 语法,它通过流式 API 调用来配置任务。
-
任务创建时机:
task xxx
是在配置文件(如 build.gradle)执行期间立即创建任务的。tasks.register('xxx')
可以延迟任务的创建,直到需要时才注册到任务注册表中。
-
可读性和维护性:
task xxx
的语法更接近传统的 Gradle 构建脚本,对于熟悉早期版本的 Gradle 的用户来说可能更易读。tasks.register('xxx')
提供了一种更一致和流畅的任务配置方式,与 Gradle 推向的 Kotlin DSL 相契合。
-
API 兼容性:
task xxx
的语法可能会在未来的 Gradle 版本中被弃用,因为 Gradle 正在推动使用 Kotlin DSL。tasks.register('xxx')
是当前推荐的方式,因为它与 Gradle 的 Kotlin DSL 兼容,并且有更好的未来兼容性保证。
-
任务名称:
task xxx
中的任务名称(‘xxx’)通常不包含引号。tasks.register('xxx')
中的任务名称必须包含引号。
-
示例:
- 使用
task xxx
语法创建一个名为 ‘myTask’ 的任务:task myTask {doLast {println 'Hello from myTask!'} }
- 使用
tasks.register('xxx')
语法创建同样的任务:tasks.register('myTask') {doLast {println 'Hello from myTask!'} }
- 使用
总的来说,虽然 task xxx
和 tasks.register('xxx')
都可以用来创建新的任务,但是 tasks.register
是更现代、更灵活且未来兼容的方式。随着 Gradle
的发展,推荐使用 Kotlin
语法和 tasks.register
方法进行任务创建和配置。
6. 自定android闭包
使用Kotlin DSL
模拟android
闭包来实现一个myandroid
的闭包,将MyAndroidBean
传入。
首先创建一个MyAndroidBean
和DefaultConfig
传参类
class MyAndroidBean {var namespace = ""var compileSdk = 0var myDefaultConfig = DefaultConfig()fun Project.myDefaultConfig(call: DefaultConfig.() -> Unit) {val defaultConfig = DefaultConfig()defaultConfig.call()}
}class DefaultConfig {var applicationId = ""var minSdk = 0var targetSdk = 0
}
然后实现一个自定义的myandroid
闭包
fun Project.myandroid(call: MyAndroidBean.() -> Unit) {val myAndroidBean = MyAndroidBean()myAndroidBean.call()val defaultConfig = myAndroidBean.myDefaultConfig//打印传参println("namespace:${myAndroidBean.namespace}")println("namespace:${myAndroidBean.compileSdk}")println("applicationId:${defaultConfig.applicationId}")println("minSdk:${defaultConfig.minSdk}")println("targetSdk:${defaultConfig.targetSdk}")
}
进行调用
myandroid {namespace = "com.heiko.mytest"compileSdk = 34myDefaultConfig {applicationId = "com.heiko.mytest"minSdk = 21targetSdk = 34}
}
7. 其他
gradle中Kotlin和Groovy的差异 :
将 build 配置从 Groovy 迁移到 Kotlin | Android Studio | Android Developers (google.cn)
Gradle Kotlin DSL 入门
Android Gradle系列文章
Android Gradle 开发与应用 (一) : Gradle基础-氦客-CSDN博客
Android Gradle开发与应用 (二) : Groovy基础语法-CSDN博客
Android Gradle开发与应用 (三) : Groovy语法概念与闭包-CSDN博客
Android Gradle开发与应用 (四) : Gradle构建与生命周期-CSDN博客
Android Gradle开发与应用 (五): 基于Gradle 8.2,创建Gradle插件-CSDN博客
Android Gradle 开发与应用 (六) : 创建buildSrc插件和使用命令行创建Gradle插件-CSDN博客
Android Gradle 开发与应用 (七) : 实现打包自动复制文件插件
Android Gradle开发与应用 (八) :Kotlin DSL
这篇关于Android Gradle开发与应用 (八) :Kotlin DSL的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!