Android Gradle 学习 - Kts Gradle学习

前言

25年主要工作是新App的开发和抽离,期间对Asm和Plugin方面工作较多,理所当然的需要和Gradle打交道,由于项目中使用的Gradle版本较低,且为Groovy版本,所以对Groovy7.0和Kts版本是如何使用的,之前看过但是没有实践过,所以就有了本篇记录文章,算是对25年上半年部分学习知识的总结。 ps:AI当道,虽然很多问题和疑惑直接让Cursor来实现就好了,但是该有的知识库积累还是要做的,好记性不如烂笔头。

Gradle简要介绍

注释:下边以Gradle kts 为例 简单展示下一般工程的项目结构图

bash 复制代码
MyAndroidApp/
├── gradle/
│   ├── wrapper/
│   │   ├── gradle-wrapper.jar          # 主要是Gradle的运行逻辑,包含下载Gradle
│   │   └── gradle-wrapper.properties   # Wrapper 配置,定义了Gradle版本
│   └── libs.versions.toml              # 版本目录(Gradle 7.0+)
│
├── app/                                # 应用模块
│   ├── build.gradle.kts                # 模块构建脚本
│   ├── proguard-rules.pro              # ProGuard 规则
│   └── src/                            # 源代码
│
├── ktslibrary/                         # 库模块(可选)
│   ├── build.gradle.kts
│   └── src/
│
├── buildSrc/                           # 自定义构建逻辑(可选)
│   ├── build.gradle.kts
│   └── src/
│
├── build.gradle.kts                    # 根项目构建脚本
├── settings.gradle.kts                 # 项目设置
├── gradle.properties                   # Gradle 属性配置
├── local.properties                    # 本地配置(不提交到 Git)
├── gradlew                             # Gradle Wrapper 脚本(Unix)
└── gradlew.bat                         # Gradle Wrapper 脚本(Windows)

gradle-wrapper.properties

kotlin 复制代码
#Tue Nov 11 20:22:16 CST 2025
//下载的Gradle的压缩包解压后的主目录
distributionBase=GRADLE_USER_HOME   
// 相对于distributionBase的解压后的Gradle的路径,为wrapper/dists
distributionPath=wrapper/dists
// Gradle版本的下载地址
distributionUrl=https://services.gradle.org/distributions/gradle-8.11.1-bin.zip
// 同distributionBase,不过是存放zip压缩包的主目录
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

和groovy版本变化不大,主要解释都在备注里了

settings.gradle.kts

kotlin 复制代码
// 1. 插件管理配置
pluginManagement {
    // 配置插件仓库
    repositories {
        // Google 的 Maven 仓库(Android 插件)
        google {
            // 内容过滤:只从 Google 下载特定包
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        
        mavenCentral()  // Maven 中央仓库
        gradlePluginPortal()  // Gradle 插件门户
    }
    
    // 插件版本解析策略
    resolutionStrategy {
        eachPlugin {
            // 自定义插件版本解析
            if (requested.id.id == "com.example.plugin") {
                useModule("com.example:plugin:${requested.version}")
            }
        }
    }
}

// 2. 依赖管理配置 三方库引入的源头配置
dependencyResolutionManagement {
    // 仓库模式
    // FAIL_ON_PROJECT_REPOS: 禁止在项目中声明仓库(推荐)
    // PREFER_PROJECT: 优先使用项目中的仓库
    // PREFER_SETTINGS: 优先使用 settings 中的仓库
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    
    // 配置依赖仓库
    repositories {
        google()
        mavenCentral()
        mavenLocal()  // 本地 Maven 仓库
        maven { url = uri("https://jitpack.io") }   // JitPack(GitHub 项目)
        // 阿里云镜像(国内加速)
        maven { url = uri("https://maven.aliyun.com/repository/public") }
        maven { url = uri("https://maven.aliyun.com/repository/google") }
    }
    
    // 版本目录
    versionCatalogs {
        // 自定义版本目录
        create("testLibs") {
            from(files("gradle/test-libs.versions.toml"))
        }
    }
}

// 3. 构建缓存配置
buildCache {
    local {
        isEnabled = true
        directory = File(rootDir, "build-cache")
        removeUnusedEntriesAfterDays = 30
    }
    
    remote<HttpBuildCache> {
        url = uri("https://build-cache.example.com/cache/")
        isEnabled = false
        isPush = false
    }
}

// 4. 插件管理(高级)
plugins {
    // 在 settings 中应用插件(Gradle 8.0+)
    id("com.gradle.enterprise") version "3.15"
}

// 5. 项目配置

// 设置根项目名称
rootProject.name = "GradleY"

// 包含模块
include ':GroovyLibrary'
include ':KtsLibrary'

// 6. Gradle Enterprise / Build Scan
gradleEnterprise {
    buildScan {
        termsOfServiceUrl = "https://gradle.com/terms-of-service"
        termsOfServiceAgree = "yes"
        publishAlways()
        // 自定义标签
        tag("CI")
        value("Git Commit", getGitCommit())
    }
}

// 辅助函数
fun getGitCommit(): String {
    return try {
        val process = Runtime.getRuntime().exec("git rev-parse --short HEAD")
        process.inputStream.bufferedReader().readText().trim()
    } catch (e: Exception) {
        "unknown"
    }
}

该文件用来配置插件管理,依赖库管理和项目相关配置,具体作用见代码注释中标注

根项目build.gradle.kts

kotlin 复制代码
// build.gradle.kts (root)

// 1. 插件声明
plugins {
    // 使用版本目录(推荐)
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.android.library) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.kotlin.jvm) apply false
    
    // 或直接声明版本
    id("com.android.application") version "8.1.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
    
    // apply false 的含义:
    // 声明版本但不应用到根项目,由子项目自己决定是否应用
}

// 为所有项目配置
allprojects {
    // 设置项目属性
    group = "com.example"
    version = "1.0.0"
    
    // 配置任务
    tasks.withType<JavaCompile>().configureEach {
        options.encoding = "UTF-8"
    }
}

// 为所有子项目配置
subprojects {
    // 应用通用插件
    apply(plugin = "checkstyle")
    
    // 配置通用依赖
    dependencies {
        // 所有子项目都添加这个依赖
        "implementation"("org.jetbrains.kotlin:kotlin-stdlib")
    }
   
}

alias(libs.plugins.android.application) apply false ,kotlin 挺好的一点就是可进行定义跳转,alias后边这里的 定义在 libs.versions.toml文件中,apply false表示不应用到跟项目,子项目可以使用。

这里还需要注意的是allprojects 是包含整个项目的配置, subprojects 不包含跟项目,只包含子项目。

app build.gradle.kts

kotlin 复制代码
// 1. 插件配置
plugins {
    // 应用插件
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.kapt)  // Kotlin 注解处理
    
    // 或直接声明
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    kotlin("kapt")  // 等同于 id("org.jetbrains.kotlin.kapt")
}

// 2. Android 基本配置
android {
    // 命名空间(AGP 7.0+,替代 manifest 中的 package)
    namespace = "com.example.app"
    // 编译 SDK 版本
    compileSdk = 33
    // 构建工具版本(可选,默认使用 AGP 推荐版本)
    buildToolsVersion = "33.0.1"
    
    // 默认配置
    defaultConfig {
        applicationId = "com.example.app"  // 应用 ID
        minSdk = 24
        targetSdk = 33
        versionCode = 1    // 版本号
        versionName = "1.0.0"
        
        // 测试运行器
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        
        // BuildConfig 字段
        buildConfigField("String", "API_BASE_URL", "\"https://api.example.com\"")
        buildConfigField("boolean", "ENABLE_LOGGING", "true")
        buildConfigField("int", "MAX_RETRY_COUNT", "3")
        
        // Vector Drawable 支持
        vectorDrawables {
            useSupportLibrary = true
        }
        
        ndk {
            // NDK 配置 支持的 ABI
            abiFilters += setOf("armeabi-v7a", "arm64-v8a")
        }
        
        multiDexEnabled = true  // 多 Dex 支持
        consumerProguardFiles("consumer-rules.pro")   // ProGuard 消费者规则
    }
    
    // 签名配置
    signingConfigs {
        getByName("debug") {        // Debug 签名
            storeFile = file("debug.keystore")
            storePassword = "android"
            keyAlias = "androiddebugkey"
            keyPassword = "android"
        }

        create("release") {        // Release 签名
            // 从 local.properties 读取
            val keystoreProperties = File(rootDir, "keystore.properties")
            if (keystoreProperties.exists()) {
                val properties = java.util.Properties()
                properties.load(keystoreProperties.inputStream())
                
                storeFile = file(properties["storeFile"] as String)
                storePassword = properties["storePassword"] as String
                keyAlias = properties["keyAlias"] as String
                keyPassword = properties["keyPassword"] as String
            }
        }
    }
    
    // 构建类型
    buildTypes {
        // Debug 类型
        debug {
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-debug"
            
            isDebuggable = true
            isMinifyEnabled = false
            isShrinkResources = false
            
            buildConfigField("String", "API_BASE_URL", "\"https://dev-api.example.com\"")
            resValue("string", "app_name", "MyApp Debug")
            
            signingConfig = signingConfigs.getByName("debug")
        }
        
        // Release 类型
        release {
            isDebuggable = false
            isMinifyEnabled = true
            isShrinkResources = true
            
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
            
            signingConfig = signingConfigs.getByName("release")
            
            buildConfigField("String", "API_BASE_URL", "\"https://api.example.com\"")
            resValue("string", "app_name", "MyApp")
        }
    }
    
    // 编译选项
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
        
        // 启用 desugaring
        isCoreLibraryDesugaringEnabled = true
    }
    
    kotlinOptions {
        jvmTarget = "11"
        
        // Kotlin 编译器参数
        freeCompilerArgs = listOf(
            "-opt-in=kotlin.RequiresOptIn",
            "-Xjvm-default=all",
            "-Xcontext-receivers"
        )
    }
    
    // 构建特性
    buildFeatures {
        viewBinding = true         // ViewBinding
        dataBinding = false        // DataBinding
        compose = false           // Compose
        buildConfig = true        // BuildConfig
        aidl = false             // AIDL
        renderScript = false      // RenderScript
        shaders = false          // Shaders
    }
    
    // Compose 配置(如果启用)
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.3"
    }
}

// 3. 依赖配置
dependencies {
    // Core
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.material)
    
    // Kotlin
    implementation(libs.kotlin.stdlib)
    implementation(libs.kotlinx.coroutines.core)
    implementation(libs.kotlinx.coroutines.android)
    
    // Android Components
    implementation(libs.androidx.activity.ktx)
    implementation(libs.androidx.fragment.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.lifecycle.viewmodel.ktx)
    
    ...
}

主要声明App bundle中使用到的依赖,构建信息设置和应用插件等信息

library build.gradle.kts

kotlin 复制代码
plugins {
    alias(libs.plugins.android.library)  // 注意是 library 不是 application
    alias(libs.plugins.kotlin.android)
}

android {
    namespace = "com.example.library"
    compileSdk = 33
    
    defaultConfig {
        minSdk = 24
        // library 没有 applicationId 和 versionCode/versionName
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        
        // 消费者 ProGuard 规则
        consumerProguardFiles("consumer-rules.pro")
    }
    
    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    
    // library 可以发布不同的变体
    publishNonDefault = true
}

dependencies {
    // api: 透传依赖 给使用此库的模块
    api(libs.kotlin.stdlib)
    
    // implementation: 不透传 仅当前模块依赖
    implementation(libs.androidx.core.ktx)
    testImplementation(libs.junit)
}

gradle libs.versions.toml

ini 复制代码
[versions]
agp = "8.10.0"
kotlin = "2.0.21"
coreKtx = "1.17.0"
junit = "4.14-SNAPSHOT"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.9.4"
activityCompose = "1.11.0"
composeBom = "2024.09.00"
appcompat = "1.7.1"
material = "1.13.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
android-library = { id = "com.android.library", version.ref = "agp" }

传统的依赖方式使用 字符串,容易拼写错误。kts的新版本依赖方式IDE 自动补全,Cmd+点击可跳转,并且版本管理更加集中

gradle.properties

properties 复制代码
# -Xmx: jvm最大堆内存(根据机器配置调整,8GB 机器建议 4096m,16GB 建议 8192m)
# -XX:MaxMetaspaceSize: 元空间最大大小
# -XX:+HeapDumpOnOutOfMemoryError: OOM 时生成堆转储
# -Dfile.encoding: 文件编码
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# 并行编译(利用多核 CPU)
org.gradle.parallel=true
# 配置缓存(实验性功能,显著提升速度) Gradle 8.0+ 稳定,强烈推荐开启
org.gradle.configuration-cache=true
# 构建缓存(复用之前的构建结果)
org.gradle.caching=true
# 按需配置  大型多模块项目建议开启
org.gradle.configureondemand=true
# 后台守护进程,避免每次构建都启动 JVM
org.gradle.daemon=true
# 文件监听(增量构建的基础)
org.gradle.vfs.watch=true
# Kotlin Daemon JVM 参数
kotlin.daemon.jvmargs=-Xmx2048m
# 增量编译
kotlin.incremental=true
# Kotlin 编译缓存
kotlin.caching.enabled=true
# Kotlin 编译器执行策略
# in-process: 在 Gradle Daemon 进程中编译(推荐)
# daemon: 使用单独的 Kotlin Daemon(默认)
# out-of-process: 每次新建进程
kotlin.compiler.execution.strategy=in-process

# 并行编译 Kotlin 模块
kotlin.parallel.tasks.in.project=true
# 使用 AndroidX
android.useAndroidX=true
# kotlin代码样式
kotlin.code.style=official
# 自动迁移第三方库到 AndroidX(通常关闭)
android.enableJetifier=false
# 使每个库的 R 类能够命名空间,让R 类只包含库本身声明的资源,不包含库依赖资源,缩小该库 R 类的大小
android.nonTransitiveRClass=true
# 使用新的资源处理器(AAPT2)
android.enableResourceOptimizations=true
# 禁用 PNG 优化(Debug 时可禁用)
# android.enablePngCrunchInDebugVariant=false
# 启用 D8 desugaring
android.enableD8.desugaring=true
# 启用 R8
android.enableR8=true
# 构建缓存
android.enableBuildCache=true

# 版本号(可被脚本读取)
VERSION_NAME=1.0.0
VERSION_CODE=1

# 签名配置(从环境变量读取,不提交到代码仓库)
# KEYSTORE_FILE=/path/to/keystore
# KEYSTORE_PASSWORD=password
# KEY_ALIAS=alias
# KEY_PASSWORD=password

# API 配置
# API_BASE_URL=https://api.example.com

# Maven 仓库用户名密码(不要提交到仓库)
# MAVEN_USERNAME=username
# MAVEN_PASSWORD=password

local.properties

properties 复制代码
# Android SDK 路径(Android Studio 自动生成)
sdk.dir=/Users/username/Library/Android/sdk
# NDK 路径
ndk.dir=/Users/username/Library/Android/sdk/ndk/25.1.8937393

# 签名配置(敏感信息)
KEYSTORE_FILE=../release.keystore
KEYSTORE_PASSWORD=mypassword
KEY_ALIAS=mykey
KEY_PASSWORD=mypassword

# API Keys(敏感信息)
GOOGLE_MAPS_API_KEY=xxx

设置sdk和ndk本地地址,配置打包签名配置等信息

Gradle的Groovy & Kotlin区别

Gradle DSL 的特点

可读性更高,更加简洁 (模版代码少一些)

scss 复制代码
// Groovy 和 kotlin都要使用到的 DSL格式,不同于java等代码方式
android {
    compileSdk = 33
    
    // 可以使用 Kotlin 的条件判断
    if (project.hasProperty("useNewApi")) {
        defaultConfig {
            minSdk = 24
        }
    }
    
    // 可以使用 Kotlin 的循环
    listOf("debug", "release").forEach { buildType ->
        println("Processing $buildType")
    }
}

// 如果不使用DSL的方式 可能会写成这样 ,稍微复杂了点
val android = project.extensions.getByType(AndroidExtension::class.java)
android.setCompileSdk(33)

val config = DefaultConfig()
config.setMinSdk(24)
android.setDefaultConfig(config)

Gradle 主要使用的内部DSL (简单说下外部DSL:需要专门的代码注解器比如 Html 和 SQL) ,可以使用 Kotlin的一些语言特性,这里还是要提到一下 Groovy的闭包,

scss 复制代码
// Gradle 的 android {} 块实际上是:调用 android() 方法, 传入一个闭包作为参数
android {  // 闭包
    compileSdk 33
}
android({ 
    compileSdk 33 
})
// 完整形态
android(new Closure() {
    void call() {
        compileSdk 33
    }
})
大概得实现逻辑
class AndroidExtension {  // 定义 Android 扩展类
    int compileSdk
    
    void defaultConfig(Closure closure) {
        def config = new DefaultConfig()
        closure.delegate = config  // 设置闭包的委托
        closure()                  // 闭包
    }
}

// 定义配置方法,接收闭包作为参数
def android(Closure closure) {
    def ext = new AndroidExtension()
    closure.delegate = ext     // 设置委托
    closure()                  // 闭包
    return ext
}

// 使用(看起来像 DSL)
android {
    compileSdk = 33      // 实际是在 AndroidExtension 上下文中
    defaultConfig {
        minSdk = 24      // 实际是在 DefaultConfig 上下文中
    }
}

Kotlin中使用的则是 Lambda方式(如果参数为最后一个,则可以去掉括号),并且Kotlin是使用 = 号来赋值的,相较于 Groovy ,Kotlin是静态类型语言,部分类型不对在编译期就会提示。

kotlin 复制代码
android {  // Lambda 表达式
    compileSdk = 33
    defaultConfig {  // 嵌套 Lambda
        minSdk = 24
    }
}

// android { } 大概实现逻辑,可以理解为 ApplicationExtension.compileSdk = 33
public fun org.gradle.api.Project.android(configure: org.gradle.api.Action<com.android.build.gradle.LibraryExtension>): kotlin.Unit { /* compiled code */ }

看Gradle源码,这里是委托给了 LibraryExtension ,所以compileSdk 字段就是 LibraryExtension 中的一个属性

所以 我们可以在Android 大括号里边使用compileSdk等字段的赋值

Groovy vs Kotlin 语法对比

  • 字符串
groovy 复制代码
// ========== Groovy ==========
def str1 = 'Hello world'      // 普通字符串 
def str3 = "Hello $name"       // 字符串插值  可以单引号,也可以双引号
kotlin 复制代码
// ========== Kotlin DSL ==========
val str1 = "only double quote"  // 只能用双引号
val str2 = "Hello $name"        // 字符串插值
  • 变量
groovy 复制代码
// ========== Groovy ==========
def name = "ymc"               // 动态类型
String name = "ymc"            // 显式类型
kotlin 复制代码
// ========== Kotlin DSL ==========
var name = "ymc"               // 可变
val name = "ymc"               // 不可变(推荐)
  • 方法调用
groovy 复制代码
// ========== Groovy ==========
println("Hello")
println "Hello"                 // 可以省略括号

add(1, 2)
add 1, 2                        // 可以省略括号和逗号

implementation 'androidx.core:core-ktx:1.9.0'
kotlin 复制代码
// ========== Kotlin DSL ==========
println("Hello")                // 必须有括号

add(1, 2)                       // 必须有括号

implementation("androidx.core:core-ktx:1.9.0")  // 必须有括号
  • plugins
groovy 复制代码
// ========== Groovy ==========
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
}

// 或
apply plugin: 'com.android.application'
kotlin 复制代码
// ========== Kotlin DSL ==========
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    kotlin("kapt")  // 等价于 id("org.jetbrains.kotlin.kapt")
}

// 或
apply(plugin = "com.android.application")
  • dependencies 块
groovy 复制代码
// ========== Groovy ==========
dependencies {
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1'
    
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
    
    testImplementation 'junit:junit:4.13.2'
}
kotlin 复制代码
// ========== Kotlin DSL ==========
dependencies {
    implementation("androidx.core:core-ktx:1.9.0")
    implementation(group = "com.google.code.gson", name = "gson", version = "2.10.1")
    
    debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
    
    testImplementation("junit:junit:4.13.2")
}
  • android 块
groovy 复制代码
// ========== Groovy ==========
android {
    namespace 'com.example.app'
    compileSdk 33
    
    defaultConfig {
        applicationId "com.example.app"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"
    }
    
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            debuggable true
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
kotlin 复制代码
// ========== Kotlin DSL ==========
android {
    namespace = "com.example.app"
    compileSdk = 33
    
    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 24
        targetSdk = 33
        versionCode = 1
        versionName = "1.0"
    }
    
    buildTypes {
        debug {
            applicationIdSuffix = ".debug"
            isDebuggable = true
        }
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

前边两段代码,比较明显的不同就是 boolean赋值,kotlin 是is开头,等号赋值

  • 集合操作
groovy 复制代码
// ========== Groovy ==========
ndk {
    abiFilters 'armeabi-v7a', 'arm64-v8a'
}

exclude '**/test/**', '**/*.tmp'
kotlin 复制代码
// ========== Kotlin DSL ==========
ndk {
    abiFilters += setOf("armeabi-v7a", "arm64-v8a")
}

exclude("**/test/**", "**/*.tmp")

最后

记得22年新版本As就已经推荐使用kotlin来管理 Gradle ,学完后感觉相比于Groovy,kotlin编译期间更加安全,跳转和代码提示 ,更科学的管理类和版本控制。

相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax