Gradle初级使用
Gradle的超强构建能力在Android Studio中可以说表现的淋漓尽致。下面我就将如何上手Gradle展开讨论。
基本知识
需要明确gradle跟maven一样,也有一个配置文件,maven里面是叫pom.xml,而在gradle中是叫build.gradle。Android Studio中的android项目通常至少包含两个build.gradle文件,一个是project范围的,另一个是module范围的,由于一个project可以有多个module,所以每个module下都会对应一个build.gradle。这么说有点抽象,看下面这个图:
这是一个android工程的project视图,上面那个是module下的build.gradle文件。下面那个是project下的build.gradle文件。这两个文件是有区别的,project下的build.gradle是基于整个project的配置,而module下的build.gradle是每个模块自己的配置。
认识build.gradle
下面看下这两个build.gradle里面的内容:
1. project里面的build.gradle:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
//构建过程依赖的仓库
repositories {
jcenter()
}
//构建过程需要依赖的库
dependencies {
//下面声明的是gradle插件的版本
classpath 'com.android.tools.build:gradle:1.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
//这里面配置整个项目依赖的仓库,这样每个module就不用配置仓库了
allprojects {
repositories {
jcenter()
}
}
这里的仓库repositories需要声明两次,这其实是由于它们作用不同,buildscript中的仓库是gradle脚本自身需要的资源,而allprojects下的仓库是项目所有模块需要的资源。所以配配的时候要注意一下。
2. module里面的build.gradle:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27//声明插件,这是一个android程序,如果是android库,应该是com.android.library
apply plugin: 'com.android.application'
android {
//安卓构建过程需要配置的参数
compileSdkVersion 21//编译版本
buildToolsVersion "21.1.2"//buildtool版本
defaultConfig {//默认配置,会同时应用到debug和release版本上
applicationId "com.taobao.startupanim"//包名
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
//这里面可以配置debug和release版本的一些参数,比如混淆、签名配置等
release {
//release版本
minifyEnabled false//是否开启混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//混淆文件位置
}
}
}
dependencies {
//模块依赖
compile fileTree(dir: 'libs', include: ['*.jar'])//依赖libs目录下所有jar包
compile 'com.android.support:appcompat-v7:21.0.3'//依赖appcompat库
}
defaultConfig中是一些基本配置,它会同时应用到debug/release版本上,下面列举了所有可配项及对应的值:
buildTypes结点很重要,这里可以配置构建的版本的一些参数,默认有两个构建版本release/debug,当然你可以自定义一个构建版本,比如叫develop,然后通过gradlew assembleDevelop就可以生成对应的apk了。
buildTypes里还有很多可配置项,下面列举了所有可配项以及debug/release版本的默认值:
认识gradle.properties
gradle相关的配置文件-gradle.properties:
从名字上就知道它是一个配置文件,没错,这里面可以定义一些常量供build.gradle使用,比如可以配置签名相关信息如keystore位置,密码,keyalias等。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
#org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.configureondemand=true
认识settings.gradle
模块配置文件settings.gradle:
这个文件是用来配置多模块的,比如你的项目有两个模块module-a,module-b,那么你就需要在这个文件中进行配置,格式如下:1
include ':module-a',':module-b'
gradle文件夹
gradle文件夹里面有两个文件,gradle-wrapper.jar和gradle-wrapper.properties,它们就是gradle wrapper。gradle项目都会有,你可以通过命令gradle init来创建它们(前提是本地安装了gradle并且配置到了环境变量中)。
gradle-wrapper.properties里面配置了gradle版本,具体内容如下:1
2
3
4
5
6#Mon Oct 30 18:06:12 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
gradlew和gradlew.bat
这分别是linux下的shell脚本和windows下的批处理文件,它们的作用是根据gradle-wrapper.properties文件中的distributionUrl下载对应的gradle版本。这样就可以保证在不同的环境下构建时都是使用的统一版本的gradle,即使该环境没有安装gradle也可以,因为gradle wrapper会自动下载对应的gradle版本。
gradlew的用法跟gradle一模一样,比如执行构建gradle build命令,你可以用gradlew build。gradlew即gradle wrapper的缩写。
gradle仓库
gradle有三种仓库,maven仓库,ivy仓库以及flat本地仓库。声明方式如下:1
2
3
4
5
6
7
8
9maven{
url "..."
}
ivy{
url "..."
}
flatDir{
dirs 'xxx'
}
单独的引入一个本地仓库可以这样写1
2
3
4
5
6repositories {
flatDir {
dirs '../im/libs2'
dirs '../lib/libs2'
}
}
有一些仓库提供了别名,可直接使用:1
2
3
4
5repositories{
mavenCentral()
jcenter()
mavenLocal()
}
gradle任务
gradle中有一个核心概念叫任务,跟maven中的插件目标类似。
gradle的android插件提供了四个顶级任务1
2
3
4assemble 构建项目输出
check 运行检测和测试任务
build 运行assemble和check
clean 清理输出任务
执行任务可以通过gradle/gradlew+任务名称的方式执,执行一个顶级任务会同时执行与其依赖的任务,比如你执行1
gradlew assemble
它通常会执行:1
2gradlew assembleDebug
gradlew assembleRelease
这时会在你项目的build/outputs/apk或者build/outputs/aar目录生成输出文件gradlew assemble
命令只能执行主module的编译任务,如果只想单独编译某一个module可以使用-p
参数来指定:1
gradlew -p module-a assembleDebug
可以通过:1
gradlew tasks
列出所有可用的任务。在Android Studio中可以打开右侧gradle视图查看所有任务。
有一个命令可以很方便的列出工程的依赖关系:1
gradle module-a:dependencies --configuration compile
这样就能知module-a编译的依赖项了。
工程配置
了解过gradle的基本配置之后,我们就可以来看看gradle在Android Studio的具体应用了。
基本配置
下面的这份清单是一个比较详细的build.gradle配置文件,包含了buildType、flavor、定义资源目录、multiDex相关等细节。完全可以满足平常一般的使用需求1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217//说明module的类型,com.android.application为程序,com.android.library为库
apply plugin: 'com.android.application'
android {
//编译的SDK版本
compileSdkVersion 22
//编译的Tools版本
buildToolsVersion "22.0.1"
//默认配置
defaultConfig {
//应用程序的包名
applicationId "com.xxx.xxx"
//支持的最低版本
minSdkVersion 14
//支持的目标版本
targetSdkVersion 19
//版本号
versionCode 100200200
//版本名
versionName "1.2.2"
// 单元测试相关的配置
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
//关闭Android Studio的PNG合法性检查的
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
//目录指向配置,比如从Eclipse迁过来的代码,和AS的文件位置不同,就需要手动设置
sourceSets {
main {
//指定AndroidManifest文件
manifest.srcFile 'AndroidManifest.xml'
//指定source目录
java.srcDirs = ['src']
//指定source目录
resources.srcDirs = ['src']
//指定source目录
aidl.srcDirs = ['src']
//指定source目录
renderscript.srcDirs = ['src']
//指定资源目录
res.srcDirs = ['res']
//指定assets目录
assets.srcDirs = ['assets']
//指定lib库目录
jniLibs.srcDirs = ['libs']
}
//指定debug模式的路径
debug.setRoot('build-types/debug')
//指定release模式的路径
release.setRoot('build-types/release')
}
//签名配置
signingConfigs {
//发布版签名配置
release {
//密钥文件路径
storeFile file("xxx.keystore")
//密钥文件密码
storePassword "xxx"
//key别名
keyAlias "xxx"
//key密码
keyPassword "xxx"
}
//debug版签名配置
debug {
//密钥文件路径,可以跟release配置不同的密钥路径
storeFile file("xxx.keystore")
//密钥文件密码
storePassword "xxx"
//key别名
keyAlias "xxx"
//key密码
keyPassword "xxx"
}
}
//build类型
buildTypes {
//发布
release {
//在编译时生成一些静态变量,这样就会在BuildConfig类中生成type字段,当然gradle默认会在BuildConfig中生成一些默认字段
buildConfigField "string","type","release"
//是否支持zip
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
//是否支持调试
debuggable false
//混淆开启
minifyEnabled true
//指定混淆规则文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
//设置签名信息
signingConfig signingConfigs.release
//设置ndk支持平台
ndk {
abiFilters "armeabi", "x86"
}
}
//调试
debug {
//在编译时生成一些静态变量,这样就会在BuildConfig类中生成type字段,当然gradle默认会在BuildConfig中生成一些默认字段
buildConfigField "string","type","debug"
//混淆不开启
minifyEnabled false
//设置签名信息
signingConfig signingConfigs.debug
//设置ndk支持平台
ndk {
abiFilters "armeabi", "x86"
}
}
}
// 打包时的相关配置。当项目中依赖的第三方库越来越多时,有可能会出现两个依赖库中存在同一个(名称)文件。
// 如果这样,Gradle在打包时就会提示错误(警告)。那么就可以根据提示,然后使用以下方法将重复的文件剔除。
packagingOptions {
exclude 'META-INF/ASL2.0'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/MANIFEST.MF'
}
lintOptions {
//lint时候终止错误上报,防止编译的时候莫名的失败
abortOnError false
//打包release版本的时候是否进行检测
checkReleaseBuilds false
}
// multiDex的一些相关配置,这样配置可以让你的编译速度更快
dexOptions {
// 让它不要对Lib做preDexing
preDexLibraries = false
// 开启incremental dexing,优化编译效率,这个功能android studio默认是关闭的。
incremental true
// 设置java堆内存大小
javaMaxHeapSize "4g"
}
// 设置产品特性,即多渠道打包的东西,比如不同的应用名,图标、AndroidManifest.xml
// 配合manifest merger使用的时候就可以达成在一次编译过程中产生多个具有自己特性配置的版本。
productFlavors {
xiaomi {
// 渠道包配置
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
manifest.srcFile 'exampleapk/AndroidManifest1.xml'
applicationId "com.xxx.xxx.xiaomi"
}
googlePlay {
applicationId "com.xxx.xxx.googleplay"
}
}
// productFlavors的批量方法,类似一个循序遍历作用。
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
//配置自定义打包名称
applicationVariants.all { variant ->
variant.outputs.each { output ->
def flavor = variant.productFlavors[0].name
def build_type = variant.buildType.name
output.outputFile = new File(
output.outputFile.parent,
"apkname_${flavor}_${build_type}_${variant.versionName}.apk".toLowerCase())
}
}
// java版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
//占位编译lib下所有jar包
provided fileTree(include: ['*.jar'], dir: 'lib')
//占位编译xxx.jar
provided files('../xxx.jar')
//编译lib目录下的.jar文件
compile fileTree(dir: 'libs', exclude: ['android-support*.jar'], include: ['*.jar'])
//编译附加的项目
compile project(':module-a')
compile project(':module-b')
compile project(':module-c')
//编译第三方开源库
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
//设置缓存时间,0即不缓存
configurations.all {
resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
}
}
基本配置的精华都在上面代码段中,仔细阅读。