Skip to content

Commit 3b455f7

Browse files
committed
add notes
1 parent 2bd8564 commit 3b455f7

File tree

7 files changed

+2242
-70
lines changed

7 files changed

+2242
-70
lines changed
+346
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
Composing builds简介
2+
===
3+
4+
在Android Studio项目中,经常会引用多个Module,而且会有多人同时参与项目开发,在这种背景下,会时常遇到版本冲突问题,出现不同的compileSdkVersion或者出现同一个库的多个不同版本等,导致我们的包体变大,项目运行时间变长,所以将依赖版本统一是一个项目优化的必经之路。
5+
6+
到目前为止Google为管理Gradle依赖提供了4种不同方法:
7+
8+
- 手动管理
9+
10+
在每个module中定义插件依赖库,每次升级依赖库时都需要手动更改(不建议使用)。
11+
12+
- ext的方式管理
13+
14+
这是Google推荐管理依赖的方法 [Android官方文档](https://developer.android.com/studio/build/gradle-tips#configure-project-wide-properties)。但是无法跟踪依赖关系,可读性差,不便维护。
15+
16+
- Kotlin + buildSrc
17+
18+
支持自动补全和单击跳转,依赖更新时将重新构建整个项目。
19+
20+
- Composing builds
21+
22+
自动补全和单击跳转,依赖更新时不会重新构建整个项目。
23+
24+
25+
26+
## Groovy ext扩展函数的替代方式
27+
28+
我们在使用Groovy语言构建项目的时候,抽取config.gradle作为全局的变量控制,使用ext扩展函数来统一配置依赖,如下:
29+
30+
![Image](https://raw.githubusercontent.com/CharonChui/Pictures/master/config_gradle.png?raw=true)
31+
32+
```groovy
33+
ext {
34+
android = [
35+
compileSdkVersion: 29,
36+
buildToolsVersion: "29",
37+
minSdkVersion : 17,
38+
targetSdkVersion : 26,
39+
versionCode : 102,
40+
versionName : "1.0.2"
41+
]
42+
43+
version = [
44+
appcompatVersion : "1.1.0",
45+
coreKtxVersion : "1.2.0",
46+
supportLibraryVersion : "28.0.0",
47+
androidTestVersion : "3.0.1",
48+
junitVersion : "4.12",
49+
glideVersion : "4.11.0",
50+
okhttpVersion : "3.11.0",
51+
retrofitVersion : "2.3.0",
52+
constraintLayoutVersion: "1.1.3",
53+
gsonVersion : "2.7",
54+
rxjavaVersion : "2.2.2",
55+
rxandroidVersion : "2.1.0",
56+
..........省略...........
57+
]
58+
59+
dependencies = [
60+
//base
61+
"constraintLayout" : "androidx.constraintlayout:constraintlayout:${version["constraintLayoutVersion"]}",
62+
"appcompat" : "androidx.appcompat:appcompat:${version["appcompatVersion"]}",
63+
"coreKtx" : "androidx.core:core-ktx:${version["coreKtxVersion"]}",
64+
"material" : "com.google.android.material:material:1.2.1",
65+
66+
//multidex
67+
"multidex" : "com.android.support:multidex:${version["multidexVersion"]}",
68+
69+
//okhttp
70+
"okhttp" : "com.squareup.okhttp3:okhttp:${version["okhttpVersion"]}",
71+
"logging-interceptor" : "com.squareup.okhttp3:logging-interceptor:${version["okhttpVersion"]}",
72+
73+
//retrofit
74+
"retrofit" : "com.squareup.retrofit2:retrofit:${version["retrofitVersion"]}",
75+
"converter-gson" : "com.squareup.retrofit2:converter-gson:${version["retrofitVersion"]}",
76+
"adapter-rxjava2" : "com.squareup.retrofit2:adapter-rxjava2:${version["retrofitVersion"]}",
77+
"converter-scalars" : "com.squareup.retrofit2:converter-scalars:${version["retrofitVersion"]}",
78+
..........省略...........
79+
]
80+
}
81+
```
82+
83+
依赖写完之后,在root路径下的build.gradle添加以下代码:
84+
85+
```groovy
86+
apply from: "config.gradle"
87+
```
88+
89+
然后在需要依赖的module下的build.gradle中:
90+
91+
```groovy
92+
dependencies {
93+
...
94+
// Retrofit + okhttp 相关的依赖包
95+
api rootProject.ext.dependencies["retrofit"]
96+
...
97+
}
98+
```
99+
100+
以上就是Groovy ext扩展函数的依赖管理方式,此方式可以做到版本依赖,但是最大的缺点就是无法跟踪代码,想要找到上面示例代码中的rootProject.ext.dependencies["retrofit"]这个依赖,需要手动切到config.gradle去搜索查找,可读性很差。
101+
102+
103+
104+
## buildSrc+kotlin
105+
106+
Android Gradle插件4.0支持在Gradle构建配置中使用Kotlin脚本 (KTS),用于替代Groovy(过去在Gradle配置文件中使用的编程语言)。
107+
108+
将来,KTS会比Groovy更适合用于编写Gradle脚本,因为采用Kotlin编写的代码可读性更高,并且Kotlin提供了更好的编译时检查和IDE支持。
109+
110+
虽然与Groovy相比,KTS当前能更好地在Android Studio的代码编辑器中集成,但采用KTS的构建速度往往比采用Groovy慢,因此在迁移到KTS时应考虑构建性能。
111+
112+
KTS:是指Kotlin脚本,这是Gradle在构建配置文件中使用的一种[Kotlin语言形式](https://kotlinlang.org/docs/tutorials/command-line.html#run-scripts)。Kotlin脚本是[可从命令行运行](https://kotlinlang.org/docs/tutorials/command-line.html#using-the-command-line-to-run-scripts)的Kotlin代码。
113+
114+
Kotlin DSL:主要是指[Android Gradle插件Kotlin DSL](https://developer.android.com/reference/tools/gradle-api),有时也指[底层Gradle Kotlin DSL](https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/)
115+
116+
117+
118+
摘自 [Gradle 文档](https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources):当运行Gradle时会检查根项目中是否存在一个名为buildSrc的目录,该目录包含了项目build相关的逻辑。然后Gradle会自动编译并测试这段代码,并将其放入构建脚本的类路径中, 对于多项目构建,只能有一个buildSrc目录,该目录必须位于根项目目录中,buildSrc是Gradle项目根目录下的一个目录,它可以包含我们的构建逻辑,与脚本插件相比,buildSrc应该是首选,因为它更易于维护、重构和测试代码。
119+
120+
buildSrc的方式,是最近几年特别流行的版本依赖管理方式。它有以下几个优点:
121+
122+
- 支持双向跟踪
123+
- buildSrc是Android默认插件,全局只有这一个地方可以修改
124+
- 支持Android Studio的代码补全
125+
126+
使用方式可参考:[Kotlin + buildSrc for Better Gradle Dependency Management](https://handstandsam.com/2018/02/11/kotlin-buildsrc-for-better-gradle-dependency-management/)
127+
128+
- 在项目根目录下新建一个名为buildSrc的文件夹( 名字必须是buildSrc,因为运行Gradle时会检查项目中是否存在一个名为buildSrc的目录 )
129+
- 在buildSrc文件夹里创建名为build.gradle.kts的文件,添加以下内容:
130+
131+
```kotlin
132+
plugins {
133+
`kotlin-dsl`
134+
}
135+
repositories{
136+
jcenter
137+
}
138+
```
139+
140+
- 在buildSrc/src/main/java/包名/目录下新建Deps.kt文件,添加以下内容:
141+
142+
```groovy
143+
object Versions {
144+
val appcompat = "1.1.0"
145+
}
146+
147+
object Deps {
148+
val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
149+
}
150+
```
151+
152+
- 重启Android Studio,项目里就会多出一个名为buildSrc的module。
153+
154+
155+
156+
157+
缺点:
158+
159+
- buildSrc 依赖更新将重新构建整个项目,项目越大,重新构建的时间就越长,造成不必要的时间浪费。
160+
161+
162+
163+
### 脚本文件命名
164+
165+
- 用Groovy编写的Gradle build文件使用.gradle文件扩展名。
166+
- 用Kotlin编写的Gradle build文件使用.gradle.kts文件扩展名。
167+
168+
### 常见误区
169+
170+
**用于定义字符串的双引号**。Groovy允许使用单引号来定义字符串,而Kotlin则要求使用双引号。
171+
172+
**基于句点表达式的字符串插值。**在Groovy中,您可以使用`$`前缀来表示基于句点表达式的字符串插值,例如以下代码段中的$project.rootDir:
173+
174+
```
175+
myRootDirectory = "$project.rootDir/tools/proguard-rules-debug.pro"
176+
```
177+
178+
但在Kotlin中,上述代码将对 `project`(而非 `project.rootDir`)调用 `toString()`。如需获取根目录的值,请使用大括号括住整个变量:
179+
180+
- `myRootDirectory = "${project.rootDir}/tools/proguard-rules-debug.pro"`
181+
- **变量分配**。一些在Groovy中适用的分配方式现在会被视作setter(或者,对于列表、集合等,则适用“addX”),因为属性在Kotlin中是只读的。
182+
183+
### 显式和隐式buildTypes
184+
185+
在Kotlin DSL中,某些buildTypes(如debug和release)是隐式提供的。但是,其他buildTypes则必须手动创建。
186+
187+
例如,在Groovy中,您可能有debug、release和staging` `buildTypes:
188+
189+
**Groovy**
190+
191+
```groovy
192+
buildTypes debug { ... } release { ... } staging { ... }
193+
```
194+
195+
在KTS中,仅debug和release` `buildTypes是隐式提供的,而staging则必须由您手动创建:
196+
197+
**KTS**
198+
199+
```
200+
buildTypes getByName("debug") { ... } getByName("release") { ... } create("staging") { ... }
201+
```
202+
203+
### 使用plugins代码块
204+
205+
如果您在build文件中使用plugins代码块,IDE将能够获知相关上下文信息,即使在构建失败时也是如此。IDE可使用这些信息执行代码补全并提供其他实用建议,从而帮助您解决KTS文件中存在的问题。
206+
207+
在您的代码中,将命令式apply plugin替换为声明式plugins代码块。Groovy中的以下代码:
208+
209+
```groovy
210+
apply plugin: 'com.android.application'
211+
apply plugin: 'kotlin-android'
212+
apply plugin: 'kotlin-kapt'
213+
apply plugin: 'androidx.navigation.safeargs.kotlin'
214+
```
215+
216+
…在 KTS 中变为以下代码:
217+
218+
```kotlin
219+
plugins {
220+
id("com.android.application")
221+
id("kotlin-android")
222+
id("kotlin-kapt")
223+
id("androidx.navigation.safeargs.kotlin")
224+
}
225+
```
226+
227+
如需详细了解plugins代码块,请参阅 [Gradle 的迁移指南](https://docs.gradle.org/nightly/userguide/migrating_from_groovy_to_kotlin_dsl.html#applying_plugins)
228+
229+
230+
231+
232+
233+
## Composing builds
234+
235+
![Image](https://raw.githubusercontent.com/CharonChui/Pictures/master/composite_build.jpeg?raw=true)
236+
237+
238+
239+
Composing builds:A composite build is simply a build that includes other builds. In many ways a composite build is similar to a Gradle multi-project build, except that instead of including single projects, complete builds are included.
240+
复合构建只是包含其他构建的构建. 在许多方面,复合构建类似于Gradle多项目构建,不同之处在于,它包括完整的builds,而不是包含单个projects:
241+
242+
- 组合通常独立开发的构建,例如,在应用程序使用的库中尝试错误修复时
243+
- 将大型的多项目构建分解为更小,更孤立的块,可以根据需要独立或一起工作
244+
245+
![Image](https://raw.githubusercontent.com/CharonChui/Pictures/master/buildsrc_composingbuild.png?raw=true)
246+
247+
**使用方式**
248+
1.新建module,名为versionPlugin(自起)
249+
2.在该module下的build.gradle文件中,添加如下代码:
250+
251+
```groovy
252+
buildscript {
253+
repositories {
254+
jcenter()
255+
}
256+
dependencies {
257+
// 因为使用的 Kotlin 需要需要添加 Kotlin 插件
258+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
259+
}
260+
}
261+
262+
apply plugin: 'kotlin'
263+
apply plugin: 'java-gradle-plugin'
264+
265+
repositories {
266+
// 需要添加 jcenter 否则会提示找不到 gradlePlugin
267+
jcenter()
268+
google()
269+
}
270+
271+
272+
compileKotlin {
273+
kotlinOptions {
274+
jvmTarget = "1.8"
275+
}
276+
}
277+
compileTestKotlin {
278+
kotlinOptions {
279+
jvmTarget = "1.8"
280+
}
281+
}
282+
283+
gradlePlugin {
284+
plugins {
285+
version {
286+
// 在app模块需要通过id引用这个插件
287+
id = 'com.hi.dhl.plugin'
288+
// 实现这个插件的类的路径
289+
implementationClass = 'com.hi.dhl.plugin.Deps'
290+
}
291+
}
292+
}
293+
```
294+
295+
3.在versionPlugin/src/main/java/包名/目录下新建Deps.kt文件,添加你的依赖配置,如:
296+
297+
```groovy
298+
package com.hi.dhl.plugin
299+
300+
class Deps : Plugin<Project> {
301+
override fun apply(project: Project) {
302+
// Possibly common dependencies or can stay empty
303+
}
304+
305+
companion object {
306+
val appcompat = "androidx.appcompat:appcompat:1.1.0"
307+
}
308+
}
309+
```
310+
311+
5.在settings.gradle文件内添加includeBuild(“versionPlugin”),注意是includeBuild哦~,Rebuild项目
312+
6.后面就可以在需要使用的gradle文件中使用了,如app下的build.gradle,在首行添加以下内容:
313+
314+
```groovy
315+
plugins {
316+
// 这个id就是在versionPlugin文件夹下build.gradle文件内定义的id
317+
id "com.hi.dhl.plugin"
318+
}
319+
```
320+
321+
注意: plugins{}需要放在app模块build.gradle文件内的首行位置
322+
323+
使用如下:
324+
325+
```groovy
326+
android {
327+
implementation Deps.appcompat
328+
}
329+
```
330+
331+
332+
333+
334+
335+
# 参考
336+
337+
- [Kotlin + buildSrc for Better Gradle Dependency Management](https://handstandsam.com/2018/02/11/kotlin-buildsrc-for-better-gradle-dependency-management/)
338+
- [How to use Composite builds as a replacement of buildSrc in Gradle](https://medium.com/bumble-tech/how-to-use-composite-builds-as-a-replacement-of-buildsrc-in-gradle-64ff99344b58)
339+
- [Stop using Gradle buildSrc. Use composite builds instead](https://proandroiddev.com/stop-using-gradle-buildsrc-use-composite-builds-instead-3c38ac7a2ab3)
340+
- [再见吧 buildSrc, 拥抱 Composing builds 提升 Android 编译速度](https://juejin.cn/post/6844904176250519565)
341+
- [composite_builds](https://docs.gradle.org/current/userguide/composite_builds.html)
342+
343+
---
344+
345+
- 邮箱 :[email protected]
346+
- Good Luck!

0 commit comments

Comments
 (0)