gradle构建工具使用,常用配置

58 阅读4分钟

说明

.gradle采用的groovy语言,而.gradle.kts用的才是kotlin语言,但为了语法高亮,均标识为kotlin

1. 依赖配置dependencies{},implementation...

// build.gradle
dependencies {
    // 语法
    // if not set version: if group is introduced in plugins{}, the version is same to the plugin, else the newest version
    implementation 'groupId:artifactId:version'
    // !!: Mandatory use this dependency
    implementation 'groupId:artifactId:version!!'
    implementation('groupId:artifactId:version') {
        // 只要是关联的子依赖,以groupId开头都会自动排除
        exclude('groupId')
        // exclude group :"com.android.support"
    }
    implementation project(path: ':mod-main')
    implementation project(':mod-main')
        
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // 区别implementation,compileOnly...
    // 添加到编译路径,即编译时能引用,编译器不报错
    // 进行打包,即运行时能引用,不报错闪退
    // 父模块,指的是依赖该模块的模块
    // 不暴露给父模块,即外部若需要引用子模块中的依赖时,需要自行引入

    /**
     * implementation
     * 添加到编译路径,进行打包,不暴露给父模块
     * 如果主模块依赖的多个子模块都使用`implementation`依赖了同一个库,Gradle的构建系统会智能地处理这种依赖关系,以避免在最终的APK中重复打包相同的库。
     */
    implementation

    /**
     * compileOnly
     * 添加到编译路径,不进行打包,不暴露给父模块
     * 此时要想项目正常运行,需要外部添implementation/api引入该依赖
     * 应用场景:只是引用了该依赖中只定义在{}外的数据,多为常量,如const val USER_INFO_DATA = "user_info_data",此时都不需要父模块再次依耐,但是光给常量单独开个模块合理吗?
     */
    compileOnly

    /**
     * runtimeOnly
     * 不添加到编译路径,进行打包,不暴露给父模块
     * 由于编译报错,直接不能打包
     * 应用场景:
     */
    runtimeOnly 'groupId:artifactId:version'
    // ???等价于
    implementation('groupId:artifactId:version') {
        scope = RuntimeScope.RUNTIME
        optional = true
    }
    
    /**
     * api
     * 添加到编译路径,进行打包,暴露给父模块
     */
    api

    /**
     * annotationProcessor kapt
     * 这两个选项本身不涉及到编译路径或打包,它们是用来处理注解的。
     * 需要注意的是,`annotationProcessor` 和 `kapt` 现在已经逐渐被替代。
     * 对于Java项目,建议使用`annotationProcessorOptions`配合`implementation`或`api`来配置注解处理器。对于Kotlin项目,则推荐使用`kapt`。
     */
    // Java的注解处理器配置
    annotationProcessor
    // Kotlin的注解处理器配置
    kapt

    /**
     * testImplementation
     * 仅在测试编译时需要的依赖,不会打包到最终jar,apk...中。
     */
    testImplementation 'groupId:artifactId:version'
    // ???等价于
    implementation('groupId:artifactId:version') {
        scope = RuntimeScope.Test
    }
    androidTestImplementation
    
    /**
     * developmentOnly
     * 
     */

}

2. 常用环境变量,自定义变量

// .gradle
// 单引号,双引号都可以表示字符串
// 双引号才支持占位符

// 常用环境变量
// 当前模块根路径
println "${projectDir}"
// project 根路径
println "${rootProject.projectDir}"
println "${rootDir}/ainow/common-build.gradle"
println "${project.rootProject.projectDir}./ainow/common-build.gradle"

// 变量使用
// 1. 在config.gradle定义,不要和系统变量冲突
ext {
    //是否单独运行某个module
    isRelease = false

    signingConfig = [
            storePassword: 'xxx',
            keyAlias     : 'xxx',
            keyPassword  : 'xxx'
    ]
}
// 2. 在project's build.gradle中
apply from: "${rootDir}/config.gradle"
//apply from: this.rootProject.file('config.gradle')

// 3. 访问变量
println "${rootProject.isRelease}"
println "${isRelease}"
println "${signingConfig.storePassword}"

3. 配置android{}

通常每个模块独立的配置

// build.gradle
android {
    // new AGP version : use namespace in build.gradle ,instead package attribute in the source AndroidManifest.xml
    // relate to R, databinding, you can use module's resourse by ${namespace}.R.xxx
    // 为包名才可以在AndroidManifest.xml简写 android:name=".MainActivity"
    // 不一定为包名
    namespace 'com.ainow.app'

    defaultConfig {
        // Application独有
        // Library projects cannot set applicationId.
        applicationId "com.ainow.app" // 系统apk唯一标识,默认为包名,可不同于包名
        versionCode 1
        versionName "1.0"
    }
    compileOptions {
        // 指定了源代码的兼容性级别为Java 17,意味着Java源代码将使用Java 17的特性进行编译,但不一定需要运行在Java 17上(除非targetCompatibility也指定为相同的版本)
        sourceCompatibility JavaVersion.VERSION_17
        // 这指定了编译后的字节码应该与Java 17兼容,意味着您的代码可以在Java 17(或更高版本,通常)上运行。
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        // 告诉Kotlin编译器生成与Java 17兼容的字节码。这是Kotlin特有的配置,因为Kotlin编译成Java字节码。
        jvmTarget = '17'
    }
    buildFeatures {
        dataBinding = true // androidx.databinding.ViewDataBinding
        viewBinding = true // ActivityMainBinding
        buildConfig true // sync后,自动生成BuildConfig类
    }
    viewBinding{
        enable=true
    }
    dataBinding{
        enable=true
    }
}

建议所有子模块应该统一的配置

// build.gradle
android {
    defaultConfig {
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = '17'
    }
}

4. 命令行

// 构建并运行,若多模块项目中有多个启动类,则都会启动
gradlew bootRun 
// tasks>build

bootJar 完整,可独立运行
jar 最小化

5. build.gradle

/**
 * 暂无用例
 * 让 compileOnly 配置继承 annotationProcessor 配置中的所有依赖
 * 这样,添加到 compileOnly 中的任何库也将被视为注解处理器,但仅在编译时使用,不会在运行时包含在内
 * */
configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}

感谢