Gradle本质上是一个Android Studio的自动化编译工具,每个module中的Project对象在编译时会运行内部所有的构建Task。Gradle就如工厂合成的工具一样,很大程度上已经制定了基本流程,但生产时总会有不同的问题,如需要配置不同的原料(Gradle参数),加入特定的工序(加入Task任务)。
一.Android基础编译流程:
官方提供的构建流程,介绍了编译打包的四个流程。
代码编译->代码合成->资源打包->签名和对齐:
- Java编译器对工程的代码资源进行编译,代码资源包括app的源代码。apt编译生成的R文件和AIDL文件生成的Java接口文件。通过Java编译器生成的xxx.class文件;
- 通过dex工具,将xxx.class文件和工程以来的第三方库文件生成虚拟机可执行的.dex文件,如使用了MultiDex,会产生多个dex文件,包含编译后的所有class文件,也包括自身的.class文件和依赖.class文件;
- aplbuilder工具将.dex文件/apt编译后的资源文件/依赖中的第三方库内的资源文件打包生成签名对齐的apk文件;
- 使用Jarsigner和Zipalign对文件进行签名和对齐操作,最终生成apk文件。
二.Instant Run:
Android Studio2.0推出了Instant Run,意瞬间编译。在编译开发中能减少应用部署和构建的时间。Gradle需要使用2.0.0以上版本,支持minSdkVersion 15以上版本。
Instant Run的整个构建流程:
代码变更->编译->应用构建->应用部署->app重启->Activity重启->完成修改变更。
Instant Run实时即时运行的机制是修改代码后,增量构建(产生增量dex的形式),然后通过判断更新资源的复杂度去选择执行热更新/温更新/或者冷更新:
- 热部署:当代码变更后传输到app内,生效时不需要重启应用。也不需要重建当前Activity。适合多数简单的修改,如方法实现的修改/变量值的修改;
- 温部署:需要Activity重启后才能看到更新,如代码修复需要变更当前页面的资源文件;
- 冷部署:app需要完全重启,但并不是重新安装。如一些继承规则/方法签名等变更的情况。
三.Gradle构建策略:
从更大的粒度分析,引入更优的Gradle优化策略,从硬件角度考虑,就需要增强电脑配置,高配置会让工程的编译速度有质的提升。同时,Android Studio也提供了一些其他优化项供我们选择。
Properties配置:
缩小考量粒度,Gradle编译过程中很大程度上是依赖JVM的运算的,那么可以考虑使用更新/更快的虚拟机,或者提升Java版本等。
再进一步缩小粒度,可以对Android Studio环境配置机制进行优化。
在项目工程gradle.properties中进行设置。
- 开启并行编译:
-
org.gradle.parallel = true
- 使用编译缓存:
-
android.enableBuildCache = true
- 保证JVM编译命令在守护进行中编译apk,daemon可以大大减少加载JVM和classes的时间:
-
org.gradle.daemon = true
- 为了在大型项目中更快地进行构建,可以配置以下的参数:
-
org.gradle.configureondemand = true
- 加大编译时Android Studio使用内存空间:
-
org.gradle.jvmargs = -Xmx3072M -XX\:MaxPermSize\=512m
四.不重复执行任务:
Library module编译时比较耗时,因为其debug和release的Task都执行了,这样就重复执行了,可以避免这种情况。
默认情况下Library只发布Release版本,并被所有依赖于Library的project依赖,这与project的build type无关,这是Android Studio本身的一种限制。
在Library module的build.gradle中添加如下代码,这样就可以同时编译debug版本:
-
defaultConfig { defaultPublishConfig 'release' publishNonDefault true }
然后在Application module中配置其他的Library module依赖:
-
dependencies { debugCompile project(path:'web',configuration:'debug') releaseCompile project(path: 'web',configuration:'release') }
此时Debug版本的Application将依赖Debug版本的Library,编译时,会跳过Library的packageReleaseJarArtfact任务,此方法有效提高了编译速度。
五.增量build:
Project是不支持Annotation processors的增量build的,它会依赖于Gradle的变化。在module中减少使用Annotation processors将有助于编译速度。
六.使用Gradle新特性:
Gradle4.1以后会添加implementation的依赖隔离模式,提供模块解耦机制,也为Gradle在构建工程时提供了最少量编译的机制。
Gradle4.1以前使用compile机制,因为底层接口时向上暴露的,如底层模块代码改动,会造成连锁效应,上层的模块也需要重新编译。为了安全起见,Gradle会完全编译整个app。所以需要更长时间。
Gradle4.1的implementation机制,因为具有跨模块接口的隐蔽性,修改波及的范围会减弱,Gradle借助implementation引用优化了代码检测机制,准确定位需要编译的模块,这样减少了编译模块。所以Android Studio3.0的工程默认都是implementation的方式引入依赖。
七.设置API新特性:
Android 5.0以后使用ART支持apk文件中加载.dex文件,ART会在app安装之前提前编译,可以扫描多个.dex文件,编译一个单独的.oat文件。
原因是每个module生成自身的.dex文件,然后不经修改直接放置apk中,看一下build过程,Android 5.0以下的版本超过方法数会执行transformClassWithMultidexlist,但是使用ART之后并不执行。
可以使用productFlavors进行配置,也可以使用buildTypes中的Debug和Release版本的配置:
-
buildTypes{ debug{ defaultConfig{minSdkVersion 21} } release{ defaultConfig{minSdkVersion 14} } }
八.极速增量编译Freeline。