组件化下多 Module 的 Gradle 管理

992 阅读3分钟

Gradle 模块化

引入一些插件时,有时需要在build.gradle中引入一些配置,比如apm,tinker等,这些其实是可以封装在相应gradle文件中,然后通过apply from引入,举个例子,例如在我们使用火山引擎时,需要在build.gradle配火山的插桩信息

应该新建一个apm_insight.gradle

apply plugin: 'apm-plugin'

ApmPlugin {
    enable !project.hasProperty("fastBuild")
    enableInDebug true
    logLevel "DEBUG"
    startSwitch = tru
    pageLoadSwitch = true
    okHttp3Switch = false
    whiteList = [
            "global",
            "com"
    ]

    blackList = [
    ]
 }

然后再在build.gradle中引入

apply from 'apm_insight.gradle'

当然也可以将gradle文件传到远端服务器上,apply一个链接地址

apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'

优点

1.单一职责原则,不与其他文件混淆

2.精简了build.gradle的代码,同时后续相关时不需要修改build.gradle的代码

Library 模块 Gradle 代码复用

项目的越来越大,Library Module也越建越多,每个Module都有自己的build.gradle但其实每个build.gradle的内容都差不多,我们可以做一个 basic 抽取,同样将共有参数/信息提取到 basic.gradle 中,每个 module apply,这样就是减少了不少代码量

//basic.gradle
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'com.google.protobuf'
apply plugin: 'com.mikefei.plugin'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'

android {

    compileSdkVersion Versions.compileSdkVersion
    buildToolsVersion Versions.buildToolsVersion

    defaultConfig {
        minSdkVersion Versions.minSdkVersion
        targetSdkVersion Versions.targetSdkVersion
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

        javaCompileOptions {

            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }

        }

        kapt {
            arguments {
                arg("AROUTER_MODULE_NAME", project.getName())
            }
        }

    }

    testOptions {
        unitTests {
            includeAndroidResources = true
        }
    }

    sourceSets {
        main {
            res.srcDirs = ['src/main/res', 'src/main/res-night']
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }

    dataBinding {
        enabled = true
    }

    buildFeatures {
        viewBinding = true
    }

    repositories {
        flatDir {
            dirs 'libs'
        }

    }

}

protobuf {

    protoc {
        artifact = 'com.google.protobuf:protoc:3.5.1:osx-x86_64' // 也可以配置本地编译器路径
    }

    generateProtoTasks {
        all().each { task ->
            task.builtins {
                remove java
            }

            task.builtins {
                java {}// 生产java源码
            }
        }

    }

}

然后在相应的模块的build.gradle中引入即可

Gradle 函数复用

各个模块中的gradle文件需要一些辅助函数,比如用于判断当前构建的任务是否是发布Google渠道,这些函数可能会被多次使用。最开始的时候只有一个gradle文件用到了,后来很多文件都会用使用,一开始并没有考虑太多,用到的时候就copy,久而久之很多文件中存在着相同的函数,十分不好维护。复用的步骤如下:

  1. 新建一个gradle文件,用于复用这些函数
  2. 这个文件中暂时还只有一个函数。除此之外,我们要做的就是把这个函数导出。导出方式也很简单:
  3. 接下来要做的就是引用了。引用就和应用插件是一样的。直接使用apply from即可
public boolean isGoogleChannel() {
    def isGoogleChannel = false
    def sp = project.gradle.startParameter
    def taskNames = sp.taskNames
    for (int i = 0; i < taskNames.size(); i++) {
        def taskName = taskNames[i]
        if (taskName != null && taskName.endsWith("Google")) {
            isGoogleChannel = tru
            break
        }
    }
  
    return isGoogleChannel
}

//导出函数
ext {
 isGoogleChannel = this.&isGoogleChannel
 }

依赖管理方式的升级

buildSrc + kotlin

config.gradle管理依赖的方法的痛点

  • 不支持代码提示补全
  • 不支持单击跳转
  • 多模块开发时,不同模块相同的依赖需要复制粘贴

使用buildSrc+kotlin可以解决上述等问题

  1. 新建 buildSrc module
  2. 新建文件 src/main/java/build.gradle.kts
plugins {
 `kotlin-dsl`
 }

repositories {
 mavenCentral()
    google()
    jcenter()
 }
  1. 新建Dependencies.kt,编写依赖代码
object Versions {
    val compileSdkVersion = 31
    val buildToolsVersion = "32.0.0"
    val minSdkVersion = 23
    val targetSdkVersion = 30
    val versionName = "4.11.0"
}

object Libs {

}
  1. 访问Dependencies.kt,支持自动补全和单击跳转
dependencies {
    api Libs.libmatisse
}

Gradle 7.0 Sharing dependency versions between projects

Gradle7.0推出了一个新的特性,使用Catalog统一依赖版本,它支持以下特性:

  1. 对所有module可见,可统一管理所有module的依赖
  2. 支持声明依赖bundles,即总是一起使用的依赖可以组合在一起
  3. 支持版本号与依赖名分离,可以在多个依赖间共享版本号
  4. 支持在单独的libs.versions.toml文件中配置依赖
  5. 支持在项目间共享依赖

还是孵化中的特性,还存在的问题:

  1. 目前在build.gradle中还不能自动补全,可能是指kts或者开发中

juejin.cn/post/699739…