天天看点

【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ⑤ ( 优化 Gradle 构建脚本 | 构建脚本结构 | 闭包定义及用法 | 依赖配置 | android 块配置 )

文章目录

  • ​​一、Gradle 构建脚本结构​​
  • ​​二、Gradle 脚本中定义闭包​​
  • ​​三、Gradle 脚本中变量的定义与使用​​
  • ​​四、dependencies 依赖设置​​
  • ​​五、设置 android 脚本块​​
  • ​​1、设置编译版本和编译工具版本​​
  • ​​2、设置 defaultConfig​​
  • ​​3、本章节完整脚本​​
  • ​​六、应用设置和依赖库设置​​
  • ​​1、应用设置​​
  • ​​2、依赖库设置​​
  • ​​3、执行配置​​
  • ​​七、Gradle 核心构建脚本完整配置代码​​

在上一篇博客 ​​【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ① ( 组件化简介 | 创建组件化应用 | 依赖库模块 / 应用模块 切换设置 )​​ 最后提到了 在 Gradle 构建脚本中 , 需要实现 依赖库模块 / 应用模块 切换设置

  • build.gradle 构建脚本 切换设置 , 切换 应用 / 依赖库 ;
  • AndroidManifest.xml 清单文件 切换设置 , 设置 启动 Activity 项 ;

在 ​​【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ② ( 组件化基本实现 | Project 相关目录 | 定义组件切换标志位 | 切换插件导入 | 切换设置应用 ID )​​ 博客中实现了 模块化 与 组件化

在 ​​【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ③ ( 在 Gradle 构建脚本中实现 AndroidManifest.xml 清单文件切换设置 )​​ 博客实现 使用 Gradle 脚本修改 AndroidManifest.xml 清单文件 ;

在 ​​【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ④ ( 使用路由实现组件间通信 | 引入 ARoute 框架 | Gradle 构建脚本优化问题 )​​ 博客中介绍 引入 ARoute 路由框架 , 实现组件间通信 , 以及 介绍 Gradle 构建脚本优化问题求 ;

在本篇博客中开始 优化 Gradle 脚本 ;

GitHub 地址 : ​​https://github.com/han1202012/Componentization​​

一、Gradle 构建脚本结构

在 工程根目录 中 , 创建 common.gradle 构建脚本 , 所有的 核心配置 都放置在该脚本中 , 在所有的模块中的 build.gradle 构建脚本 中 都使用如下 ​

​apply from:​

​ 代码 , 导入 common.gradle 构建脚本 到 模块中的 build.gradle 脚本中 ;

/**
 * 此处直接导入 common.gradle 构建脚本
 */
apply from: "${rootProject.rootDir}/common.gradle"      

在 common.gradle 构建脚本 中调用了 dependencies 方法

同时在 模块中的 build.gradle 构建脚本中 , 还可以 继续调用 dependencies 方法 , 在已设置依赖的基础上 , 追加新的依赖

/**
 * 此处直接导入 common.gradle 构建脚本
 */
apply from: "${rootProject.rootDir}/common.gradle"

/**
 * dependencies 闭包配置可以调用多次
 */
dependencies {
    // 注意此处 api 需要进行依赖传递 , 在其它模块中也需要调用 base 模块中的内容
    api project(':base')
}      

注意上述代码中的 api 依赖配置 , 需要进行 依赖传递 , 一般进行底层开发 , 自己开发底层库时才需要传递依赖 , 使用 api 依赖配置会增加 Gradle 构建的时间 , 非必要不用 ;

上述 base 依赖库 , 在各个模块都需要调用到 , 因此做了依赖传递 , 也可以在每个模块中配置 ​

​implementation project(':base')​

​ 替代上述 api 类型的依赖 ;

绝大多数的导入依赖操作使用的是 implementation 配置 , 不进行依赖传递 ;

二、Gradle 脚本中定义闭包

参考 ​​【Groovy】闭包 Closure ( 自定义闭包参数 | 自定义单个闭包参数 | 自定义多个闭包参数 | 闭包参数默认值指定 )​​ 博客理解 ;

下面的代码中 , 定义了 setAndroidConfig 闭包 , 传入 project.android 配置对象作为闭包的参数

/**
     * 定义闭包 , 传入 project.android 配置对象
     * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
     * 因此可以使用 project.android 获取该配置对象
     */
    setAndroidConfig = {
        android ->
            // 闭包具体执行内容
    }      

三、Gradle 脚本中变量的定义与使用

在 Android 的 Gradle 构建脚本中 , 尽量将用到的 变量 , 闭包 , 方法 定义在 Project 的扩展属性 中 , 这样可以在各个 构建脚本 中可以直接使用 ; 定义的方法如下 :

project.ext {
  变量名 = 变量值
  闭包名 = {
    闭包参数 ->
      闭包执行内容
  }
}      

定义变量示例 : 定义变量直接使用 ​

​变量名 = 变量值​

​ 的方式进行定义即可 ;

/**
 * 定义 Project 对象的 ext 属性扩展
 */
project.ext {
    /*
        注意 : 所有的变量都要定义在 构建脚本 最前面 ,
        构建脚本是一个顺序执行的脚本 ,
        变量一定要定义在最前面 ;
     */

    /**
     * 该变量控制当前的运行模式
     *      组件化 : 在 Debug 开发阶段, 每个模块都可以独立运行, 因此相关的模块都是 Application 应用模块,
     * 此时, isModuleDebug 设置为 true. ( 单独运行 )
     *      模块化 : 在 Release 发布阶段, 只有一个壳应用是可以独立运行的, 其它所有的模块都作为依赖库存在,
     * 此时, isModuleDebug 设置为 false. ( 非单独运行 )
     */
    isModuleDebug = true

    /**
     * build.gradle 构建脚本中使用到的编译相关版本号
     */
    compileSdkVersion = 32
    buildToolsVersion = "32.0.0"
    minSdkVersion = 18
    targetSdkVersion = 32
    versionCode = 1
    versionName = "1.0"

    /**
     * 主应用的 applicationId
     */
    applicationId = "kim.hsl.componentization"
}      

使用变量 : 一般都是在闭包中使用变量 , 这里注意 闭包中的属性查找策略 , 在闭包中访问属性 , 查找顺序为 this -> owner -> delegate , 这个查找策略可以通过 调用闭包的 setResolveStrategy 方法进行修改 ; 在闭包里使用属性时 , 必须指明该属性是谁的 , 如 : project.compileSdkVersion , 说明该属性是定义在 Project 中的, 也就是我们自己使用 ext 扩展的属性 , 否则就会触发上述 this -> owner -> delegate 顺序查找机制 ;

setAndroidConfig = {
        android ->
            /**
             * 这里注意闭包中的属性查找策略
             * 在闭包中访问属性 , 查找顺序为 this -> owner -> delegate
             * 这个查找策略可以通过调用闭包的 setResolveStrategy 方法进行修改
             * 在闭包里使用属性时 , 必须指明该属性是谁的 , 如 : project.compileSdkVersion
             * 说明该属性是定义在 Project 中的, 也就是我们自己使用 ext 扩展的属性
             * 否则就会触发上述 this -> owner -> delegate 顺序查找机制
             */
            android.compileSdkVersion project.compileSdkVersion
            android.buildToolsVersion project.buildToolsVersion
  }      

四、dependencies 依赖设置

首先 , 定义依赖库集合 , 这里 使用 map 集合 存储 依赖库 , 键 为 依赖库名称 , 值 为 依赖库的完整路径 ( 依赖库组名:依赖库名称:依赖库版本号 )

/**
     * 定义 map 集合 libs
     * Key : 依赖库名称
     * Value : 依赖库的完整路径 依赖库组名:依赖库名称:依赖库版本号
     * 之后如果设置新的依赖 , 都添加到 libs 目录下
     */
    libs = [
            "k-stdlib"        : "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
            "ktx"             : "androidx.core:core-ktx:1.8.0",
            "appcompat"       : "androidx.appcompat:appcompat:1.5.1",
            "material"        : "com.google.android.material:material:1.6.1",
            "constraintlayout": "androidx.constraintlayout:constraintlayout:2.1.4",
            "arouter"         : "com.alibaba:arouter-api:1.5.1" // 组件化框架
    ]      

注意 , 将不同的依赖类型进行分开 , 这是 annotationProcessor 类型的依赖 , 用于配置注解处理器 ;

// 组件化框架的 注解处理器 依赖
    apts = [
            "ARouterCompiler": "com.alibaba:arouter-compiler:1.5.1",
    ]      

然后 , 定义闭包 , 在闭包中遍历上述 map 集合 , 逐个使用 implementation 设置不传递的依赖 ;

/**
     * 定义闭包 , 在该闭包中设置依赖
     */
    setDependencies = {
        dependencies ->
            delegate = dependencies

            /*
                设置一系列的 implementation 依赖
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation 'androidx.core:core-ktx:1.8.0'
                implementation 'androidx.appcompat:appcompat:1.5.1'
                implementation 'com.google.android.material:material:1.6.1'
                implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
             */
            project.libs.each {
                k, v -> implementation v
            }

            /**
             * 设置注解处理器依赖
             */
            project.apts.each {
                k, v -> annotationProcessor v
            }

            testImplementation 'junit:junit:4.+'
            androidTestImplementation 'androidx.test.ext:junit:1.1.3'
            androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

            /**
             * 主应用需要依赖业务模块
             */
            if (project.name == 'app' && !project.isModuleDebug) {
                implementation project(':business')
            }
    }      

五、设置 android 脚本块

定义闭包 , 传入 project.android 配置对象 , 该配置对象是在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置 ;

1、设置编译版本和编译工具版本

/**
             * 这里注意闭包中的属性查找策略
             * 在闭包中访问属性 , 查找顺序为 this -> owner -> delegate
             * 这个查找策略可以通过调用闭包的 setResolveStrategy 方法进行修改
             * 在闭包里使用属性时 , 必须指明该属性是谁的 , 如 : project.compileSdkVersion
             * 说明该属性是定义在 Project 中的, 也就是我们自己使用 ext 扩展的属性
             * 否则就会触发上述 this -> owner -> delegate 顺序查找机制
             */
            android.compileSdkVersion project.compileSdkVersion
            android.buildToolsVersion project.buildToolsVersion      

相当于

compileSdkVersion 32
                    buildToolsVersion "32.0.0"      

配置 ;

2、设置 defaultConfig

/**
             * 设置 " build.gradle#android#defaultConfig " 脚本块配置
             */
            android.defaultConfig {

                /**
                 * 为了避免 applicationId , 各个模块的 applicationId 不能重复
                 * app 模块中使用 applicationId 作为应用 ID 即可
                 * 其它依赖库模块使用 applicationId + 模块名称 作为应用 ID
                 * ( 在组件化调试模式下 , 发布状态时不添加 )
                 */

                // 默认的 应用 ID
                // app 模块不管什么模式下 , 其应用 ID 都是 "kim.hsl.componentization"
                applicationId project.applicationId

                // 组件化模式下需要为每个模块设置 应用 ID
                if (project.isModuleDebug) {
                    // 组件化模式下 , 应用 ID 设置为 applicationId + 模块名称
                    applicationId project.applicationId
                    // 设置后缀
                    applicationIdSuffix = project.name
                } else {
                    // 模块化状态下 , 暂时不需要设置
                }

                minSdkVersion project.minSdkVersion
                targetSdkVersion project.targetSdkVersion
                versionCode project.versionCode
                versionName project.versionName

                testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

                javaCompileOptions {
                    // 为注解处理器设置路由模块名称
                    annotationProcessorOptions {
                        // 路由模块名称
                        arguments += [AROUTER_MODULE_NAME: project.name]
                    }
                }
            }      

3、本章节完整脚本

其它配置都可参考 ​​【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ③ ( 在 Gradle 构建脚本中实现 AndroidManifest.xml 清单文件切换设置 )​​ 博客最终配置 ;

完整设置脚本 :

/**
     * 定义闭包 , 传入 project.android 配置对象
     * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
     * 因此可以使用 project.android 获取该配置对象
     */
    setAndroidConfig = {
        android ->
            /*  主要是进行如下设置
                android {
                    compileSdkVersion 32
                    buildToolsVersion "32.0.0"

                    defaultConfig {
                        if (project.isModuleDebug) {
                            applicationId "kim.hsl.business"
                    }
                    minSdkVersion 18
                    targetSdkVersion 32
                    versionCode 1
                    versionName "1.0"

                    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
                }
             */
            /**
             * 这里注意闭包中的属性查找策略
             * 在闭包中访问属性 , 查找顺序为 this -> owner -> delegate
             * 这个查找策略可以通过调用闭包的 setResolveStrategy 方法进行修改
             * 在闭包里使用属性时 , 必须指明该属性是谁的 , 如 : project.compileSdkVersion
             * 说明该属性是定义在 Project 中的, 也就是我们自己使用 ext 扩展的属性
             * 否则就会触发上述 this -> owner -> delegate 顺序查找机制
             */
            android.compileSdkVersion project.compileSdkVersion
            android.buildToolsVersion project.buildToolsVersion

            /**
             * 设置 " build.gradle#android#defaultConfig " 脚本块配置
             */
            android.defaultConfig {

                /**
                 * 为了避免 applicationId , 各个模块的 applicationId 不能重复
                 * app 模块中使用 applicationId 作为应用 ID 即可
                 * 其它依赖库模块使用 applicationId + 模块名称 作为应用 ID
                 * ( 在组件化调试模式下 , 发布状态时不添加 )
                 */

                // 默认的 应用 ID
                // app 模块不管什么模式下 , 其应用 ID 都是 "kim.hsl.componentization"
                applicationId project.applicationId

                // 组件化模式下需要为每个模块设置 应用 ID
                if (project.isModuleDebug) {
                    // 组件化模式下 , 应用 ID 设置为 applicationId + 模块名称
                    applicationId project.applicationId
                    // 设置后缀
                    applicationIdSuffix = project.name
                } else {
                    // 模块化状态下 , 暂时不需要设置
                }

                minSdkVersion project.minSdkVersion
                targetSdkVersion project.targetSdkVersion
                versionCode project.versionCode
                versionName project.versionName

                testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

                javaCompileOptions {
                    // 为注解处理器设置路由模块名称
                    annotationProcessorOptions {
                        // 路由模块名称
                        arguments += [AROUTER_MODULE_NAME: project.name]
                    }
                }
            }

            android.buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles android.getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                }
            }
            android.compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
            }
            android.kotlinOptions {
                jvmTarget = '1.8'
            }

            android.sourceSets {
                main {
                    if (project.name != 'app') {
                        if (project.isModuleDebug) {
                            //可运行模块
                            manifest.srcFile "src/main/debug/AndroidManifest.xml"
                        } else {
                            //依赖库模块
                            manifest.srcFile "src/main/AndroidManifest.xml"
                        }
                    } else {
                        // app 应用中的清单文件默认即可 , 可以不设置
                        manifest.srcFile "src/main/AndroidManifest.xml"
                    }
                }
            }
    }      

六、应用设置和依赖库设置

1、应用设置

定义闭包 , 传入一个 project 参数 , 闭包作用是导入 可执行应用 模块的插件 ; 应用设置中 , 导入的是 ‘com.android.application’ 插件 ;

/**
     * 定义闭包 , 传入一个 project 参数
     * 闭包作用是导入 可执行应用 模块的插件
     *
     * 如果当前的模块是 可执行应用 模块 , 则调用该闭包执行
     * 如果当前的模块是 依赖库 模块 , 则调用另外的 闭包
     */
    setApplicationDefaultConfig = {
        project ->
            // 导入 com.android.application 插件
            project.apply plugin: 'com.android.application'
            project.apply plugin: 'kotlin-android'

            /**
             * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
             * 因此可以使用 project.android 获取该配置对象
             */
            setAndroidConfig project.android
            /**
             * 设置构建脚本中的依赖
             */
            setDependencies project.dependencies
    }      

2、依赖库设置

依赖库设置与应用设置唯一的不同是 , 依赖库 导入 com.android.application 插件 ;

setLibraryDefaultConfig = {
        project ->
            // 导入 com.android.application 插件
            project.apply plugin: 'com.android.library'
            project.apply plugin: 'kotlin-android'

            /**
             * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
             * 因此可以使用 project.android 获取该配置对象
             */
            setAndroidConfig project.android
            /**
             * 设置构建脚本中的依赖
             */
            setDependencies project.dependencies
    }      

3、执行配置

定义完上述配置之后 , 需要根据 当前的 组件化 / 模块化 状态 和 模块的类型 统一执行 setApplicationDefaultConfig 或 setLibraryDefaultConfig

注意 : app 主应用 始终都是 Application 应用 , 不受 isModuleDebug 控制 , 其它模块在组件调试时 , 所有模块都是可执行模块 , 在发布时 , 所有模块都是依赖库模块 ;

/**
 * app 主应用 始终都是 Application 应用 , 不受 isModuleDebug 控制
 * 其它模块在组件调试时 , 所有模块都是可执行模块
 * 在发布时 , 所有模块都是依赖库模块
 */
if (isModuleDebug || project.name == 'app') {
    // 应用模块 , 组件调试时所有的模块都必须可执行
    project.setApplicationDefaultConfig project
} else {
    // 依赖库模块
    project.setLibraryDefaultConfig project
}      

七、Gradle 核心构建脚本完整配置代码

/**
 * 定义 Project 对象的 ext 属性扩展
 */
project.ext {
    /*
        注意 : 所有的变量都要定义在 构建脚本 最前面 ,
        构建脚本是一个顺序执行的脚本 ,
        变量一定要定义在最前面 ;
     */

    /**
     * 该变量控制当前的运行模式
     *      组件化 : 在 Debug 开发阶段, 每个模块都可以独立运行, 因此相关的模块都是 Application 应用模块,
     * 此时, isModuleDebug 设置为 true. ( 单独运行 )
     *      模块化 : 在 Release 发布阶段, 只有一个壳应用是可以独立运行的, 其它所有的模块都作为依赖库存在,
     * 此时, isModuleDebug 设置为 false. ( 非单独运行 )
     */
    isModuleDebug = true

    /**
     * build.gradle 构建脚本中使用到的编译相关版本号
     */
    compileSdkVersion = 32
    buildToolsVersion = "32.0.0"
    minSdkVersion = 18
    targetSdkVersion = 32
    versionCode = 1
    versionName = "1.0"

    /**
     * 主应用的 applicationId
     */
    applicationId = "kim.hsl.componentization"

    /*
            implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
            implementation 'androidx.core:core-ktx:1.8.0'
            implementation 'androidx.appcompat:appcompat:1.5.1'
            implementation 'com.google.android.material:material:1.6.1'
            implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
     */
    /**
     * 定义 map 集合 libs
     * Key : 依赖库名称
     * Value : 依赖库的完整路径 依赖库组名:依赖库名称:依赖库版本号
     * 之后如果设置新的依赖 , 都添加到 libs 目录下
     */
    libs = [
            "k-stdlib"        : "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
            "ktx"             : "androidx.core:core-ktx:1.8.0",
            "appcompat"       : "androidx.appcompat:appcompat:1.5.1",
            "material"        : "com.google.android.material:material:1.6.1",
            "constraintlayout": "androidx.constraintlayout:constraintlayout:2.1.4",
            "arouter"         : "com.alibaba:arouter-api:1.5.1" // 组件化框架
    ]

    // 组件化框架的 注解处理器 依赖
    apts = [
            "ARouterCompiler": "com.alibaba:arouter-compiler:1.5.1",
    ]

    /**
     * 定义闭包 , 传入一个 project 参数
     * 闭包作用是导入 可执行应用 模块的插件
     *
     * 如果当前的模块是 可执行应用 模块 , 则调用该闭包执行
     * 如果当前的模块是 依赖库 模块 , 则调用另外的 闭包
     */
    setApplicationDefaultConfig = {
        project ->
            // 导入 com.android.application 插件
            project.apply plugin: 'com.android.application'
            project.apply plugin: 'kotlin-android'

            /**
             * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
             * 因此可以使用 project.android 获取该配置对象
             */
            setAndroidConfig project.android
            /**
             * 设置构建脚本中的依赖
             */
            setDependencies project.dependencies
    }

    setLibraryDefaultConfig = {
        project ->
            // 导入 com.android.application 插件
            project.apply plugin: 'com.android.library'
            project.apply plugin: 'kotlin-android'

            /**
             * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
             * 因此可以使用 project.android 获取该配置对象
             */
            setAndroidConfig project.android
            /**
             * 设置构建脚本中的依赖
             */
            setDependencies project.dependencies
    }

    /**
     * 定义闭包 , 传入 project.android 配置对象
     * 在 com.android.application 插件中 , 对 Project 进行了扩展 , 声明了 android 扩展配置
     * 因此可以使用 project.android 获取该配置对象
     */
    setAndroidConfig = {
        android ->
            /*  主要是进行如下设置
                android {
                    compileSdkVersion 32
                    buildToolsVersion "32.0.0"

                    defaultConfig {
                        if (project.isModuleDebug) {
                            applicationId "kim.hsl.business"
                    }
                    minSdkVersion 18
                    targetSdkVersion 32
                    versionCode 1
                    versionName "1.0"

                    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
                }
             */
            /**
             * 这里注意闭包中的属性查找策略
             * 在闭包中访问属性 , 查找顺序为 this -> owner -> delegate
             * 这个查找策略可以通过调用闭包的 setResolveStrategy 方法进行修改
             * 在闭包里使用属性时 , 必须指明该属性是谁的 , 如 : project.compileSdkVersion
             * 说明该属性是定义在 Project 中的, 也就是我们自己使用 ext 扩展的属性
             * 否则就会触发上述 this -> owner -> delegate 顺序查找机制
             */
            android.compileSdkVersion project.compileSdkVersion
            android.buildToolsVersion project.buildToolsVersion

            /**
             * 设置 " build.gradle#android#defaultConfig " 脚本块配置
             */
            android.defaultConfig {

                /**
                 * 为了避免 applicationId , 各个模块的 applicationId 不能重复
                 * app 模块中使用 applicationId 作为应用 ID 即可
                 * 其它依赖库模块使用 applicationId + 模块名称 作为应用 ID
                 * ( 在组件化调试模式下 , 发布状态时不添加 )
                 */

                // 默认的 应用 ID
                // app 模块不管什么模式下 , 其应用 ID 都是 "kim.hsl.componentization"
                applicationId project.applicationId

                // 组件化模式下需要为每个模块设置 应用 ID
                if (project.isModuleDebug) {
                    // 组件化模式下 , 应用 ID 设置为 applicationId + 模块名称
                    applicationId project.applicationId
                    // 设置后缀
                    applicationIdSuffix = project.name
                } else {
                    // 模块化状态下 , 暂时不需要设置
                }

                minSdkVersion project.minSdkVersion
                targetSdkVersion project.targetSdkVersion
                versionCode project.versionCode
                versionName project.versionName

                testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

                javaCompileOptions {
                    // 为注解处理器设置路由模块名称
                    annotationProcessorOptions {
                        // 路由模块名称
                        arguments += [AROUTER_MODULE_NAME: project.name]
                    }
                }
            }

            android.buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles android.getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                }
            }
            android.compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
            }
            android.kotlinOptions {
                jvmTarget = '1.8'
            }

            android.sourceSets {
                main {
                    if (project.name != 'app') {
                        if (project.isModuleDebug) {
                            //可运行模块
                            manifest.srcFile "src/main/debug/AndroidManifest.xml"
                        } else {
                            //依赖库模块
                            manifest.srcFile "src/main/AndroidManifest.xml"
                        }
                    } else {
                        // app 应用中的清单文件默认即可 , 可以不设置
                        manifest.srcFile "src/main/AndroidManifest.xml"
                    }
                }
            }
    }

    /**
     * 定义闭包 , 在该闭包中设置依赖
     */
    setDependencies = {
        dependencies ->
            delegate = dependencies

            /*
                设置一系列的 implementation 依赖
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation 'androidx.core:core-ktx:1.8.0'
                implementation 'androidx.appcompat:appcompat:1.5.1'
                implementation 'com.google.android.material:material:1.6.1'
                implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
             */
            project.libs.each {
                k, v -> implementation v
            }

            /**
             * 设置注解处理器依赖
             */
            project.apts.each {
                k, v -> annotationProcessor v
            }

            testImplementation 'junit:junit:4.+'
            androidTestImplementation 'androidx.test.ext:junit:1.1.3'
            androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

            /**
             * 主应用需要依赖业务模块
             */
            if (project.name == 'app' && !project.isModuleDebug) {
                implementation project(':business')
            }
    }
}

/**
 * app 主应用 始终都是 Application 应用 , 不受 isModuleDebug 控制
 * 其它模块在组件调试时 , 所有模块都是可执行模块
 * 在发布时 , 所有模块都是依赖库模块
 */
if (isModuleDebug || project.name == 'app') {
    // 应用模块 , 组件调试时所有的模块都必须可执行
    project.setApplicationDefaultConfig project
} else {
    // 依赖库模块
    project.setLibraryDefaultConfig project
}