目录
1、gradle是什么?
2、在android项目中如何使用gradle?
3、gradle编译、打包android项目机制是怎样的?
4、为什么公司的项目每次编译打包那么慢?如何优化?
1、gradle是什么?
1.1、gradle是什么?
gradle是个自动化构建工具,与Ant、Maven等类似。它和编程语言、IDE都无直接关系。
1.2、gradle在android项目中起到什么作用?
既然是构建工具,自然就负责项目构建相关的工作,比如项目的编译、运行、签名、打包、依赖管理等
1.3、gradle既然与IDE无关,android studio是怎么使用gradle的?
为了能让AS使用gradle,google特意做了AS插件:AndroidGradlePlugin。
这个android插件定义了编译、打包等任务,当我们使用gradle命令去打包时,就是去执行插件里写好的任务,完成编译打包。
插件的使用:
在项目模块的build.gradle里声明引用插件,如:
apply plugin: 'com.android.application'(主模块),
或者 apply plugin: 'com.android.library'(依赖库)
2、在android项目中如何使用gradle?
1、在android项目中如何使用gradle?
只要配置好一些基本的gradle配置文件,就可以使用gradle命令管理android项目了
2、有哪些基础配置文件?都是干嘛的?如何配置?
使用android studio创建android项目会自动生成gradle的配置文件,如下:
1.根目录下的build.gradle。
这是整个android项目的gradle基础配置文件。一般在这里声明gradle构建脚本的配置和项目的全局配置。
2.各模块目录下的build.gradle。
这是当前模块(module)的gradle配置文件。一般在这里声明和本模块相关的配置。
3.根目录下的settings.gradle。
这是项目编译所需模块的声明配置。一般在这里声明哪些module应该被加入到编译过程。
4.根目录下的gradle.properties。
这是gradle构建环境设置。一般在这里设置开启守护进程、并行编译之类的。
3、使用gradle编译、打包android项目怎样实现的?
1、如何使用gradle实现编译、打包?
执行gradle命令就可以实现了,最常见的比如输入:gradle build。
至于具体是如何实现的,这就要说到gradle里的task(任务)这个概念。
我们在输入gradle build命令后,其实是让gradle执行了一个build task。
这个build task实现了编译、打包项目的工作。
build task里又有一系列的task,比如lint检查(check)、编译打包(assemble)等task,每个task又由更具体细小的task去实现。
至于task具体如何操作,是由gradle的android插件定义好的。
- 更具体的构建过程与gradle task讲解,可以参考:
1、android studio的gradle插件官方文档(点击查看,需要vpn)
2、其他博客的gradle构建过程理解(点击查看)
4、为什么公司的项目每次编译打包那么慢?是因为有依赖传递吗?如何优化?
4.1、为什么公司的项目每次编译打包那么慢?是因为依赖传递重复编译吗?
项目编译慢确实是依赖传递导致的,但不是因为重复编译。
真正原因是因为每次编译都要把所有模块全编译一遍,每次要编译的代码和资源太多了,导致项目编译慢。
1、先讲下依赖传递:
我们人为地创造一个依赖传递的情况。
假设现在项目里有3个模块,主模块A,库模块B、C。
主模块A依赖B,B又依赖C。这样就导致了依赖传递。
结果就是:
修改了A里的代码,打包时会重新编译A。编译A的时候,由于A依赖B所以也要编译B;
编译B时,由于B又依赖C,所以也要编译C。
导致最后需要将A、B、C三个模块都编译一遍。
如果模块数量多一些(十几个),每次要编译的东西就会很多,导致项目编译速度慢。
2、再讲下重复编译:
假设主模块A依赖B,B又依赖C。现在主模块除了依赖B又得依赖C了。
那编译A时,会把A依赖的模块都编译一遍。
A依赖B,会编译B、C。A又依赖C,那还得编译C。
这样会不会导致编译2遍模块C呢?答案是:不会。
因为gradle在编译前会遍历所有build.gradle配置,生成编译依赖树。
如果有重复的编译任务,只会保留一个编译任务,重复的任务都会被忽略掉。
查看模块里的task的依赖树:
进入想查看的模块目录下,输入gradle dependencies。
可以看到当前模块里所有的依赖关系树,以生成debug包的task为例,如图:
可以看到主模块app依赖有:
1.com.android.support:appcompat-v7:23.4.0
2.com.android.support:design:23.4.0
3.project :gradletest
4.project :gradletest2
而模块gradletest又依赖1和4,在依赖树中可以看到gradletest的依赖被忽略了(带*表示忽略),这就避免了重复编译。
4.2、如何优化?
【答】
1、在gradle配置里设置一些优化配置。比如开启守护进程、并行编译、增量编译等。
2、还有就是把不怎么常修改的模块打包成aar,直接依赖aar,就不用每次都编译该模块了。
gradle依赖请参考:
国人翻译的gradle文档,第八章:依赖管理基础(点击查看)gradle查看task的依赖(非库依赖)
gradle task流程可视化(点击查看)grale编译加速的具体配置
加快gradle 构建速度的经验(点击查看)