Gradle Kotlin 规范插件用于模块化结构 - 共享构建逻辑

article/2025/8/26 13:04:56

Gradle Kotlin 规范插件用于模块化结构 - 共享构建逻辑

gradle logo
我们中的许多人都遇到过Groovy的困难,并习惯于将其转换为Kotlin DSL。 然后,作为Android工程师,在完全使用Kotlin编写的项目上工作是纯粹的喜悦。

我们假设采用基于功能的模块化应用程序结构,并应用版本目录(version catalog)功能。我们将充分管理构建逻辑,使其集中化并可由模块重用。
以下是通过创建您的自定义插件脚本来促进Gradle构建配置成为集中化构建逻辑的步骤。

我们所有人都通常采用的方法是将自定义脚本放置到默认的buildSrc模块中。先前不推荐使用buildSrc实现,因为它会使构建缓存失效,并在每次更改依赖项时同步整个项目。它现在被视为Gradle 8中的一个包含式构建。

项目级声明

在项目设置脚本中,我们将配置脚本移动到一个构建逻辑复合构建模块中。
第一个 pluginManagement 块确保 Gradle 使用适当的插件存储库。我们将我们的新模块包含在构建中,并明确指定我们需要的存储库。
另一个关键元素是集中式依赖声明中的解析模式,你可以声明以强制 Gradle 始终获取正确的依赖项。在此示例中,我们将使用项目设置中声明的存储库。

settings.gradle.kts

@file:Suppress("UnstableApiUsage")enableFeaturePreview("VERSION_CATALOGS")
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")pluginManagement {includeBuild("build-logic")repositories {gradlePluginPortal()google()mavenCentral()}
}dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)repositories {google()mavenCentral()}
}rootProject.name = "GradleKotlinConventionPlugins"include(":app")

在这里插入图片描述

共享逻辑复合模块

在设置脚本中启用版本目录功能后,我们开始使用新的复合模块。

settings.gradle.kts

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {versionCatalogs {create("libs") {from(files("../gradle/libs.versions.toml"))}}
}rootProject.name = "build-logic"

现在,我们将我们的新模块定义为Kotlin脚本,通过启用Kotlin DSL并强制使用预编译的脚本插件将其作为 Kotlin 源集的一部分。
因此,作为项目构建的组成部分的复合模块负责配置,这通常是我们在项目级 Gradle 构建脚本中处理的。 我们将 Gradle 特定的声明移动到那里。

build.gradle.kts

plugins {`kotlin-dsl``kotlin-dsl-precompiled-script-plugins`
}repositories {google()mavenCentral()gradlePluginPortal()
}dependencies {implementation(libs.kotlin.gradlePlugin)implementation(libs.gradle)
}tasks.test {useJUnitPlatform()
}

类型为基础的规范

在基于特征的模块化应用结构中,我们有主应用模块、功能模块和共享模块(用于一些可重用的逻辑或数据)等。

我们确定的主要规范插件包括:

  • Kotlin 库规范
  • Android 库规范
  • Android 可组合库规范

Kotlin 库规范

Kotlin 库惯例通常用于声明一些 API 或共享一些逻辑。它是一个覆盖了 JDK 版本的 Java 库。

kotlin-library-conventions.gradle.kts

plugins {`java-library`kotlin("jvm")
}kotlin {jvmToolchain(jdkVersion = 11)
}task("testUnitTest") {dependsOn("test")
}

gradle-kotlin

Kotlin Android 库规范

Kotlin Android 库规范适用于默认启用 ViewBinding 功能的特征模块。

kotlin-android-library-conventions.gradle.kts

plugins {id("com.android.library")kotlin("android")
}@Suppress("UnstableApiUsage")
android {. . .compileOptions {isCoreLibraryDesugaringEnabled = truetargetCompatibility = JavaVersion.VERSION_11sourceCompatibility = JavaVersion.VERSION_11}kotlinOptions {jvmTarget = JavaVersion.VERSION_11.toString()}buildFeatures {viewBinding = true}
}dependencies {. . .
}

Kotlin Android Compose库规范

它是先前库约定的扩展,具有与 Jetpack Compose 相关的声明。

kotlin-android-composable-library-conventions.gradle.kts

plugins {id("kotlin-android-library-conventions")
}@Suppress("UnstableApiUsage")
android {buildFeatures.compose = truecomposeOptions.kotlinCompilerExtensionVersion = libs.versionKotlinCompiler
}dependencies {implementation(platform(libs.libAndroidxComposeBom))implementation(libs.libAndroidxComposeFoundation)
}

创建新模块时,通过应用传统插件和额外的依赖项来定义构建脚本会更加容易。我们也可以考虑将组合模块应用于另一个项目。

当我们创建一个新模块时,可以通过应用公约插件和附加的依赖项,更容易地定义构建脚本。我们还可以考虑将组合模块应用于另一个项目。

feature-build.gradle.kts

plugins {id("kotlin-android-library-conventions")id("test-conventions")
}dependencies {implementation(libs.androidX.appCompat)implementation(libs.google.material)
}

结论

总之,模块化是我们解决诸多问题的主要关注点,如代码库大小、可扩展性、可读性、代码质量、代码重复等。我们通常会按照特性来划分模块,将特性代码进行隔离。Google Android团队最近也发布了一份应用程序模块化指南,采用了相同的方法。

https://developer.android.com/topic/modularization

但也有一些与版本目录相关的限制性问题。库不是直接可访问的,我们需要创建一些扩展函数来解决这个问题。插件在插件块中也不被识别。这个问题似乎在Gradle 8中已经得到解决。

您可以在我的Github规范repository中找到所有的源代码。

https://github.com/uteke/gradle-kotlin-convention-plugins


http://www.hkcw.cn/article/YOceHqcBSq.shtml

相关文章

Gradle开发手册-高级篇之多模块项目创建

在进阶篇中详细讲解了gradle配置相关的详细内容。但是是基于单module的配置,在实际开发时基本全是多module类型的项目。所以本章我们就系统学习下如何构建多模块项目(父-子)以及相关的task内容。 基础篇:从概念以及广度上介绍下gradle的核心内容,并构建一个简单的java项目;…

Gradle的版本差异导致无法编译:Could not initialize class com.android.build.gradle.internal.TaskManager

运行项目报错:Could not initialize class com.android.build.gradle.internal.TaskManager 我这边的原因是少了SDK的包和JDK版本不对。 我们先区分下gradle version与gradle plugin version。如果对此不了解,经常会由于Gradle的版本号问题造成项目无法编译&#xf…

Gradle版本目录(Version Catalog)

Gradle版本目录(Version Catalog) “版本目录是一份依赖项列表,以依赖坐标表示,用户在构建脚本中声明依赖项时可以从中选择。” 我们可以使用版本目录将所有依赖项声明及其版本号保存在单个位置。这样,我们可以轻松地在模块和项目之间共享依…

android开发之NDK配置开发

1、打开项目后,一次点击Tools>SDK Manager 2、点击SDK Tools标签页 3、选中NDK(Side by Side)和CMake复选框 4、点击OK 此时系统会显示一个对话框,告诉你NDK软件包占用了多少磁盘空间 5、点击OK 6、安装完成后,点击…

如何在没有计算机的情况下将联系人从 iPhone 传输到安卓

如果您正在考虑从 iPhone 迁移到Android ,您可能想知道如何在不丢失任何重要信息的情况下转移联系人。您可能还想避免使用电脑进行此过程。幸运的是,有几种方法可以教您如何在不使用电脑的情况下将联系人从 iPhone 迁移到Android ,而且这些方…

如何将数据从 iPhone 传输到 vivo 的 4 种方法

在运行不同操作系统的 iPhone 和 Vivo 之间传输数据时,需要谨慎。廉价或不安全的在线解决方案可能会失败,并使您的个人数据面临风险。避免被“免费”和“快速”服务的承诺所诱惑,因为这可能会危及您的数据。 在本文中,我们整理了…

图片转换之heic转jpg(使用ImageMagick)

缘由:iphone的图库,用jpg拍照保存后内存占比较大,heic格式会微缩不少。问题来了,电脑不能直接小图预览heic。 分析:现在就是解决小图预览的问题(大图用wps可以看) 解决:查找了一些…

Android导入项目时Gradle下载速度慢\超时\失败解决方法

Android导入项目时Gradle下载速度慢\超时\失败解决方法 原因分析: 这是因为Gradle源服务器在国外,下载速度自然很慢 distributionUrlhttps\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 解决方法: 最可靠的方法就是换源 &…

从 iPhone 传输到Android 3 种简单方法

使用 iPhone 多年后,也许您想切换到Android并尝试一些新的东西?不管您是否相信,如果您确实做出了这样的决定,您很可能会遇到将数据从 iPhone 传输到Android的问题。由于手机数据对于当今的人们来说非常重要,因此当您切换到另一部手机时丢失它是不明智的。 在本指南中,您…

Contactile三轴触觉力传感器的滑动与摩擦力计算能力

Contactile三轴触觉力传感器通过先进的技术设计,实现了滑动与摩擦力的精准计算。传感器通过分析滑动与振动信号的关联,动态计算摩擦系数,同时捕捉力、扭矩及初始滑动等多维数据。这种能力为机器人提供了高度灵活的触觉反馈,满足复…

国产分子动力学引擎——GPUMD本地部署教程:专为 NVIDIA GPU 加速设计

一、简介 GPUMD 是一款开源分子动力学模拟软件,由渤海大学樊哲勇教授团队主导开发,2017年首发1.0版本,持续迭代至3.9.4版本,是国内首个完全基于GPU加速的开源分子动力学软件,专为 NVIDIA GPU 加速设计。它使用 CUDA 提…

PostgreSQL 备份与恢复策略

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

2025年渗透测试面试题总结-匿名[校招]高级安全工程师(代码审计安全评估)(题目+回答)

安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。、 目录 匿名[校招]高级安全工程师(代码审计安全评估) 渗透基础 1. 自我介绍 2. SQL注入写Shell(分数…

Cmake编译glog成功并在QT中测试成功步骤

glog是开源的日志记录系统,下载地址GitHub - google/glog: C implementation of the Google logging module 跟gflags有点相似,编译和测试过程比较周折,所以记录下来具体的编译和测试步骤。 编译环境:WindowsCmakeVs2022Qt5.14.…

【Linux】网络--传输层--深入理解TCP协议

个人主页~ 深入理解TCP协议 一、TCP数据传输问题1、发送数据丢包问题---重传机制(一)客户端数据发送丢包(二)服务器确认应答丢包(三)时间间隔问题 2、三次握手问题---奇数次握手(一)…

深入理解 SQL 的 JOIN 查询:从基础到高级的第一步

在处理数据库时,我们常常需要从多个表中提取数据。比如想知道一个城市的天气情况,同时又想知道这个城市的具体位置。这就需要将 weather 表和 cities 表结合起来查询。这种操作在 SQL 中被称为 JOIN 查询。 现在看下两种表的情况 1.weather 表&#xff…

【无标题】C++23新特性:支持打印volatile指针

文章目录 前言背景与问题C23的解决方案实现原理使用场景硬件开发多线程调试 总结 前言 在C开发中,volatile关键字常用于修饰变量,以确保编译器不会对这些变量进行优化,从而保证程序能够正确地与硬件交互或处理多线程环境下的特殊变量。然而&…

RPG15.轻攻击

上一篇已经制作了装备和卸下武器 接下来开始做战斗系统 1.先添加Tag ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(InputTag_EquipAxe);ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(InputTag_UnEquipAxe); ARPG_GRIVITY_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Play…

20250529-C#知识:继承、密封类、密封方法、重写

C#知识:继承、密封类、密封方法、重写 继承是面向对象的三大特性之一,通过继承能够减少重复代码的编写,有助于提升开发效率。 1、继承 C#不同于C,只支持单继承当子类出现与父类同名的成员时,父类成员被隐藏&#xff0…

第30次CCF计算机软件能力认证-1-重复局面

时间限制: 1.0 秒 空间限制: 512 MiB 下载题目目录(样例文件) 题目背景 国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。 题目描述 国际象棋每一个局面可以用大小为 88…