什么是Gradle
Gradle是基于Apache Ant和Apache Maven概念的自动化构建工具。他使用一种基于Groovy的DSL来声明项目设置。
Gradle能够:
自动处理包相依关系(取自 Maven Repos 的概念)
自动处理布署问题(取自 Ant 的概念)
条件判断写法直觉(使用 Groovy 语言)
Gradle的编译过程
Gradle中有两个对象:Project、Task。
每个项目的编译至少有一个Project,一个build.gradle就代表一个project,每个project里面包含了多个task,task里包含了多格action。action包含了需要被执行的代码。
编译过程中,Gradle会根据build相关文件,聚合所有的project和task,执行task中的action。
执行顺序由依赖逻辑来保证。所有的task都需要依赖其他task来执行,没有被依赖的task首先被执行。
编译过程分为:
1.初始化阶段: 创建project对象。
2.配置阶段: 执行所有的编译脚本,同事创建project的所有task。
3.gradle根据传入的参数决定如何执行这些task。
Gradle Files
setting.gradle 用于定义加入编译过程的module
顶层的build.gradle 最终被应用到所有项目中
顶层的build.gradle
buildscript: 定义了Android编译工具的类路径。
allprojects: 定义的属性会被应用到所有module中。
每个项目的build.gradle
1.apply plugin: 定义了gradle插件。
eg:
1 | apply plugin "com.android.application" |
2.android: 用于配置android的所有特殊配置。这个是前年声明的plugin提供的
(1)defaultConfig: 程序的默认配置。
(2)buildType: 定义了编译类型。可以针对每个类型进行不同的配置。(release。debug等)
3.dependencies: 是gradle的依赖配置。定义了当前项目需要依赖的其他库。
Gradle Wrapper
gradle wrapper用于处理对以往项目的兼容性问题。
Gradle basics
Gradle会根据build文件的配置生成不同的task。我们可以直接单独执行每个task。
可以使用./gradlew task
列出所有的task。如果想要列出每个task对应依赖的其他task,可以使用./gradlew task -all
Android tasks
基本的四个task:
1.assemble: 对所有的buildType 生成apk包
2.clean: 移除所有的编译输出文件,比如apk包
3.check: 执行lint检测编译
4.build: 同时执行assemble和check命令
Configuration
BuildConfig
可以在buildTypes中配置一些key-value对。他们会体现在BuildConfig中
repositories
Repositories: 就是代码仓库,我们平时的添加的一些 dependency就是从这里下载的,Gradle 支持三种类型的仓库:Maven,Ivy和一些静态文件或者文件夹。
在执行阶段,gradle会从仓库中取出对应需要的依赖文件。
除了使用远程库以外,还可以使用相对路径配置本地仓库:
1 | repositorys { |
Local dependencies
File dependencies
通过files()方法可以添加文件依赖,也可以通过fileTree()添加一个文件夹:
1 | dependencies { |
Native libraries
配置本地.so
库:
1 | android { |
Library projects
如果要写一个library项目让其他项目引用,则需要使用一下plugin:
1 | apply plugin: 'com.android.library' |
Build Variants
编译时动态根据当前的编译类型输出不用样式的apk文件。这时候就需要使用buildType了
BuildType
Source Sets
每当创建新的build type的时候,gradle默认会创建一个信息source set。我们可以建立与main文件夹同级的文件夹,根据编译类型的不同可以选择对某些源码直接进行替换。
Product flavors
前面build type的做法能够对同一份源码编译同一个程序的不同类型,如果我们需要针对同一份源码编译不同的程序,就需要用到Product flavors;
所有的product flavor版本和defaultConfig共享所有属性
和build type一样,product flavor也有自己的source set文件夹。除此之外,build type和product flavor可以结合,他们的文件夹里面的文件优先级甚至高于单独的build type和product flavor文件夹的优先级。
1 | android { |
Signing configurations
签名相关。
当我们打包市场版时,我们需要输入keystore数据,如果是debug版本系统会帮我们配置这些信息。这些信息在gradle中都配置在signingConfigs中:
1 | android { |
配置之后可以再build type中直接使用
1 | android { |
Optimize
Speeding up multimodule builds
可以通过以下方式加快gradle编译:
开启并行编译: 在项目根目录下的gradle.properties中设置
1 | org.gradle.parallel=true |
开启编译守护进程: 该进程在第一次启动后会一直存在,当第二次编译的时候,可以重用该进程。
1 | org.gradle.daemon=true |
加大可用编译内存:
1 | org.gradle.jvmargs=-Xms256m -Xmx1024m |
Reducing apk file
在编译时,我们可能会有很多资源并没有用到,此时可以通过shrinkResources
来优化我们的资源文件,除去不必要的资源
1 | android { |
某些情况下,一些资源需要通过动态加载的方式载入,这时候就需要在res/raw/下简历一个keep.xml文件,通过以下方式keep资源:
1 | <?xml version="1.0" encoding="utf-8"?> |
Manual shrinking
对于一些特殊文件或者文件夹,例如国际化资源文件、屏幕适配资源等。如果我们已经确定过了某种幸好,而不需要重新适配,就可以去掉不可能被适配的资源:
1 | android{ |
Profiling
当我们执行所有task的时候,都可以添加–profile参数生成一份执行报告在reports/profile
中。
Practice
在开发中,我们可能需要自己自定义task。这就需要用到Groovy了。
Groovy
Groovy我打算专门去学习一下。这里就不记录了。
通过hook Android编译插件重命名apk
1 | android.applicationVariants.all { |
学习资料来自:https://www.jianshu.com/p/9df3c3b6067a