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编译期间更加安全,跳转和代码提示 ,更科学的管理类和版本控制。

相关推荐
祈澈菇凉1 小时前
Next.js 零基础开发博客后台管理系统教程(八):提升用户体验 - 表单状态、加载与基础验证
前端·javascript·ux
电商API大数据接口开发Cris1 小时前
淘宝 API 关键词搜索接口深度解析:请求参数、签名机制与性能优化
前端·数据挖掘·api
小周同学1 小时前
vue3 上传文件,图片,视频组件
前端·vue.js
细心细心再细心1 小时前
runtime-dom记录备忘
前端
小猪努力学前端1 小时前
基于PixiJS的小游戏广告开发
前端·webgl·游戏开发
哆啦A梦15881 小时前
62 对接支付宝沙箱
前端·javascript·vue.js·node.js
用户8168694747251 小时前
Lane 优先级模型与时间切片调度
前端·react.js
虎头金猫1 小时前
MateChat赋能电商行业智能导购:基于DevUI的技术实践
前端·前端框架·aigc·ai编程·ai写作·华为snap·devui
LiuMingXin1 小时前
CESIUM JS 学习笔记 (持续更新)
前端·cesium