Android Gradle开发与应用 (八) :Kotlin DSL

2024-04-14 15:04

本文主要是介绍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的主要编写语言了。

我们去创建KotlinGradle的时候,可以发现,它里面的内容和以前的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方法会返回一个PluginDependencySpecPluginDependencySpec中有versionapply方法

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 DSLKotlin 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 DSLKotlin DSL 在语法和风格上的差异导致了配置插件扩展时的不同写法。Groovy DSL 提供了更加直接和简洁的语法,而 Kotlin DSL 则强调了类型安全和清晰的代码结构。这些差异使得两种 DSL 都有其独特的优点,开发者可以根据个人喜好和项目需求选择使用哪一种。

5.2 gradle中,tasks.register(‘xxx’)和task xxx这两种新建Task方式,有什么区别 ?

在Gradle中,tasks.register('xxx')task xxx这两种方式用于新建Task, 但它们之间存在一些区别:

  1. Groovy 和 Kotlin 语法:

    • task xxx 是 Groovy 语法,它使用 Groovy 闭包来配置任务。
    • tasks.register('xxx') 是 Kotlin 语法,它通过流式 API 调用来配置任务。
  2. 任务创建时机:

    • task xxx 是在配置文件(如 build.gradle)执行期间立即创建任务的。
    • tasks.register('xxx') 可以延迟任务的创建,直到需要时才注册到任务注册表中。
  3. 可读性和维护性:

    • task xxx 的语法更接近传统的 Gradle 构建脚本,对于熟悉早期版本的 Gradle 的用户来说可能更易读。
    • tasks.register('xxx') 提供了一种更一致和流畅的任务配置方式,与 Gradle 推向的 Kotlin DSL 相契合。
  4. API 兼容性:

    • task xxx 的语法可能会在未来的 Gradle 版本中被弃用,因为 Gradle 正在推动使用 Kotlin DSL。
    • tasks.register('xxx') 是当前推荐的方式,因为它与 Gradle 的 Kotlin DSL 兼容,并且有更好的未来兼容性保证。
  5. 任务名称:

    • task xxx 中的任务名称(‘xxx’)通常不包含引号。
    • tasks.register('xxx') 中的任务名称必须包含引号。
  6. 示例:

    • 使用 task xxx 语法创建一个名为 ‘myTask’ 的任务:
      task myTask {doLast {println 'Hello from myTask!'}
      }
      
    • 使用 tasks.register('xxx') 语法创建同样的任务:
      tasks.register('myTask') {doLast {println 'Hello from myTask!'}
      }
      

总的来说,虽然 task xxxtasks.register('xxx') 都可以用来创建新的任务,但是 tasks.register 是更现代、更灵活且未来兼容的方式。随着 Gradle 的发展,推荐使用 Kotlin 语法和 tasks.register 方法进行任务创建和配置。

6. 自定android闭包

使用Kotlin DSL模拟android闭包来实现一个myandroid的闭包,将MyAndroidBean传入。

首先创建一个MyAndroidBeanDefaultConfig 传参类

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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/903296

相关文章

Python使用Tkinter打造一个完整的桌面应用

《Python使用Tkinter打造一个完整的桌面应用》在Python生态中,Tkinter就像一把瑞士军刀,它没有花哨的特效,却能快速搭建出实用的图形界面,作为Python自带的标准库,无需安装即可... 目录一、界面搭建:像搭积木一样组合控件二、菜单系统:给应用装上“控制中枢”三、事件驱动:让界面“活”

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

Python Flask 库及应用场景

《PythonFlask库及应用场景》Flask是Python生态中​轻量级且高度灵活的Web开发框架,基于WerkzeugWSGI工具库和Jinja2模板引擎构建,下面给大家介绍PythonFl... 目录一、Flask 库简介二、核心组件与架构三、常用函数与核心操作 ​1. 基础应用搭建​2. 路由与参

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

Kotlin Compose Button 实现长按监听并实现动画效果(完整代码)

《KotlinComposeButton实现长按监听并实现动画效果(完整代码)》想要实现长按按钮开始录音,松开发送的功能,因此为了实现这些功能就需要自己写一个Button来解决问题,下面小编给大... 目录Button 实现原理1. Surface 的作用(关键)2. InteractionSource3.