1.复合构建介绍
Gradle 3.3(不是 gradle 插件) 开始支持复合构建。复合构建是包含其他构建的构建。复合构建类似于 gradle 多项目构建,不同之处在于不包括单个项目,而是包括完整的构建。
多项目构建和复合构建非常相似,可以从两种构建方式关注点上区分的:
- 多项目构建关注点是:如何组织多个项目,项目之间往往是存在业务逻辑联系的。比如一个商城项目包含了前台部分和后台管理部分,那可以分成两个子项目来做(fun-shop/front 和 fun-shop/admin)
- 复合构建关注点是:如何整合多个独立的项目,被引入的项目是可以独立运行的,但不一定有逻辑联系。比如一个项目,它依赖公司另一个独立的 SDK,这个 SDK 可以作为独立的项目运行。
复合构建允许:
- 组合通常独立开发的构建,例如在应用程序使用的库中尝试 bug 修复时
- 将大型多项目构建分解为更小、更独立的块,这些块可以根据需要单独或一起工作
一个构建需要满足什么条件才能被复合构建引入?
- 必须要有 settings.gradle 文件
- 构建本身不能是复合构建
- 构建的 rootProject.name 属性不能与其它被引入的构建的该属性相同
- 构建的 rootProject.name 属性不能与复合构建的最顶层级工程的该属性相同
- 构建的 rootProject.name 属性不能与复合构建的该属性相同
2. 官方使用教程
官方 demo (基于 gradle 的工程):
https://docs.gradle.org/current/userguide/composite_builds.html#included_plugin_builds
简约地说就是三种方式:
方式一:通过 gradle 命令行的 --include-build 选项实现复合构建
工程结构:(其中 my-app、my-utils 都是可以独立运行的工程)
/samples/compositeBuilds/basic
|--my-app
|--build.gradle
|--src/main/java
|--my-utils
|--number-utils
|--src/main/java
|--string-utils
|--src/main/java
|--build.gradle
|--setting.gradle
my-app 依赖:
dependencies {
compile "org.sample:number-utils:1.0"//<--依赖number-utils子项目的产出结果
compile "org.sample:string-utils:1.0"//<--依赖string-utils子项目的产出结果
}
在 my-app 目录下运行命令行:gradle --include-build …/my-utils run 即可实现复合构建
方式二:在 setting.gradle 文件中使用 includeBuild 语句声明复合构建
my-app/build.gradle 的配置依旧不变:
dependencies {
compile "org.sample:number-utils:1.0"//<--依赖number-utils子项目的产出结果
compile "org.sample:string-utils:1.0"//<--依赖string-utils子项目的产出结果
}
my-app/setting.gradle:
rootProject.name = 'my-app'
includeBuild '../my-utils'
直接运行 my-app 即可
3. 导入到 IDEA
组合构建最有用的特性之一是 IDE 集成。通过将 idea 或 eclipse 插件应用于您的构建,可以生成一个 idea 或 eclipse 项目,从而允许组合中的所有构建一起开发。
除了这些 Gradle 插件之外,IntelliJ IDEA 和 Eclipse Buildship 的最新版本还支持直接导入复合构建。
导入复合构建允许来自单独Gradle构建的源轻松地一起开发。对于每个包含的构建,每个子项目都作为IDEA模块或Eclipse项目包含。配置源依赖项,提供跨构建导航和重构
那在 Android Studio 中如何使用呢?在 AppProject settings.gradle 中配置了复合构建后,我们打开 AppProject:

3. 在 Android 中如何使用?
我们这边主要调研复合构建在 Android 中的应用,调研工程地址:
https://igit.58corp.com/android-survey/tunable
工程结构

SDKProject
包含一个 sdk lib 和 demo app, sdk lib 中只有一个类:
package com.wuba.survey.sdk.core;
public final class StringUtils {
private StringUtils() {
}
public static String concat(String str) {
return "[Tunable]: " + str;
}
}
我们可以发布 aar 到 maven:com.turn.test.sdk:TestSDK:xxx
AppProject
app 依赖:
dependencies {
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 依赖 maven aar
implementation 'com.turn.test.sdk:TestSDK:1.0.0'
}
settings:
include ':app'
// 复合构建 + 依赖替换
includeBuild('../SDKProject') {
dependencySubstitution {
substitute module('com.turn.test.sdk:TestSDK') with project(':TestSDK')
}
}
1. includeBuild 可以实现自动导入 SDKProject 项目,并使 AppProject 构建前先构建 SDKProject
2. 使用依赖替换将 'com.turn.test.sdk:TestSDK 替换为 SDKProject 中的 TestSDK 工程
大胆想象一下:使用复合构建 + 依赖替换是不是可以解决我们平时开发过程中,在接入方 APP 中调试 SDK/解 SDK bug 的问题