Kotlin scripting 的优势
关于开发者来说,保证整个项目中言语和代码的一致性是很重要的。尤其是关于 Android 开发者来说,运用 Kotlin 言语编写事务代码,同样也希望运用 Kotlin 言语来构建项目。尽管 Kotlin 脚本 现在还是 Experimental 的,可是 Gradle Kotlin DSL 现已满足成熟和稳定,能够胜任 Android 的构建办理
除此之外,Kotlin 脚本相关于 Groovy 来说可读性更高,也更利于 IDE 的语法查看、主动补全和跳转。所以迁移至 Kotlin 脚本是一个很好的挑选
基础运用
尖端 settings.gradle.kts
尖端 settings.gradle.kts
用来界说工程级的库房装备以及用来构建应用的 module
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "My Application"
include(":app")
pluginManagement()
用来装备各种 Gradle 插件的装备,包含插件所属库房、依靠处理策略、依靠版别等
dependencyResolutionManagement()
用来装备 Project 以及各个子 module 共用的库房和依靠(module 独有的依靠最好在 module 自己的 build.gradle.kts
中装备)
尖端 build.gradle.kts
尖端 build.gradle.kts
用来界说 Project 以及各个子 module 共用的插件和特点
plugins {
id("com.android.application") version "8.2.0-alpha02" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
}
尽管能够运用如下的办法界说 module 共用的特点,可是为了解耦,尽量不要这样用
ext {
extra["sdkVersion"] = 33
extra["appcompatVersion"] = "1.6.1"
}
// compileSdk = rootProject.extra["sdkVersion"]
module 级 build.gradle.kts
module 级 build.gradle.kts
用来装备 module 自己的依靠和装备信息
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.yourapp.myapplication"
compileSdk = 33
defaultConfig {
applicationId = "com.yourapp.myapplication"
minSdk = 24
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
}
Groovy 迁移
弥补赋值的 =
,如 compileSdkVersion 30
变为 compileSdk = 33
调整字符串语法,如 "$project.rootDir/tools/proguard-rules-debug.pro"
变为 "${project.rootDir}/tools/proguard-rules-debug.pro"
用 val
/var
替换 def
进行变量声明,如 def building64Bit = false
变为 val building64Bit = false
调整 list 和 map 语法,如 jvmOptions += ["-Xms4000m", "-Xmx4000m"]
变为 jvmOptions += listOf("-Xms4000m", "-Xmx4000m")
最佳实践
上面咱们现已提到,在尖端 build.gradle.kts
中界说 module/subproject 共用的特点不利于解耦,那各个 module 怎么高雅地增加中心化的 dependency 和 version 呢?
一种比较好的方式是运用 Gradle version catalog,运用方式就像直接运用目录层级引用相同,如:
implementation(libs.accompanist.systemuicontroller)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.core.ktx)
前提是需要在根目录下的 gradle 目录下创立一个 libs.versions.toml
文件,它运用 TOML(一种简练高效的装备文件格式)格式来书写,在这里咱们能够用来声明 [versions]
, [libraries]
, [bundles]
, [plugins]
,如:
[versions]
accompanist = "0.28.0"
androidGradlePlugin = "8.0.0"
androidxActivity = "1.7.0"
[libraries]
accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
依靠能够用多种方式来声明,"com.mycompany:mylib:1.4"
, { module = "com.mycompany:other", version = "1.4" }
或许 { group = "com.mycompany", name = "alternate", version = "1.4" }
都能够
假如你不想用默认的 libs
目录名,能够这样来自界说名字:
dependencyResolutionManagement {
defaultLibrariesExtensionName.set("projectLibs")
}
version catalog 是类型安全的,编译器会主动查看和主动补全。假如在某些场景下不可用,能够测验运用不安全的 API:
val versionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
versionCatalog.findLibrary("accompanist-systemuicontroller").ifPresent {
implementation(it)
}
}
假如想要在多个团队或许多个项目中共享一个 version catalog 文件,能够这样依靠本地文件:
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
或许更灵敏一点,把 version catalog 以插件的方式运用:
plugins {
`version-catalog`
`maven-publish`
}
catalog {
versionCatalog {
library("my-lib", "com.mycompany:mylib:1.2")
}
}
publishing {
publications {
create<MavenPublication>("maven") {
from(components["versionCatalog"])
}
}
}
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from("com.mycompany:catalog:1.0")
version("accompanist", "0.28.0")
}
}
}
总之,咱们最终期望的,都是一个类型安全的、中心化的、灵敏解耦的依靠和版别办理,运用 Kotlin + version catalog 现在来说是一个比较好的方案
参阅
- Configure your build
- Gradle Kotlin DSL Primer
- Sharing dependency versions between projects