Android应用程序使用开源的Gradle构建系统来构建。Gradle是在Java世界中广泛使用的、易定制化的现代化API。Android的Gradle插件针对Android应用程序添加了大量的特性,包括构建类型(build type)、定制(product flavor)、签名管理(signing configuration)、库项目(library project)等。
include ':app'
include语句表示app子目录是唯一的子项目。如果你添加一个Android库项目,其也会被添加到这个文件。
你可以在构件文件顶层添加所有子项目或模块通用的配置选项。
buildscript {
repositories {
jcenter()
maven { url 'https://dl.google.com/dl/android/maven2/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// 注意:不要把你的应用程序依赖放在这里;它们属于各独立模块的build.gradle文件。
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Gradle的安装本身默认不包含Android的功能。Google为Gradle提供了一个Android的插件,其简化了Android项目的配置。构建文件顶层的buildscript块告诉Gradle去哪下载这个插件。
正如你看到的,默认这个插件会从jcenter下载,即Bintray JCenter Artifactory库。也支持其他的库(特别是mavenCentral(),默认的Maven仓库),但是JCenter现在已经成默认的了。JCenter中的内容都使用HTTPS连接并通过CDN来提供,同时也更快速。
allprojects段顶层项目和所有子项目都默认使用jcentrer()仓库来下载所有的Java第三方依赖库。
Gradle允许你自定义你自己的task,并插入到有向无环图(Directed Acyclic Graph,DAG),Gradle用其解析task之间的关系。这里一个clean task被添加到了构建的顶端。type: Delete
表示这个新的task是Gradle内置的Delete task的一个自定义实例。在这个例子中,这个task将构建目录从根项目中删除,默认构建目录即顶层中的build。
apply plugin: 'com.android.application'
android {
// 前两个都应该被赋予最新可用的版本,因为他们都是向后兼容的,并且包含了所有当前的漏洞修复。
compileSdkVersion 27 // 目标编译环境
buildToolsVersion '26.0.2' // 构建工具的版本
defaultConfig {
// 应用程序的“package”名字,在Google Play中应该是唯一的。
// 这个值在你的应用程序的整个生命周期都不能被改变。
// 改变这个值会使你的应用程序被认为是一个全新的应用程序,也就没法更新。
// 这个值是Android Manifest根元素下的一个package的属性。
applicationId "link_work.elderlycommunity"
// 应用程序支持的最小版本
minSdkVersion 19
// 应用程序目标的Android版本。如果该值没有被设置为最新版本,
// Android Studio会发出警告。
targetSdkVersion 27
// 版本号
versionCode 1
// 字符串,发行版本
versionName "1.0"
flavorDimensions "versionCode"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
// 表示app期望使用的SDK版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// APP签名,密钥创建过程请看下文。
signingConfigs {
config {
// 用户名
keyAlias 'androiddebugkey'
// 密码
keyPassword 'android'
// 秘钥保存地址
storeFile file('./debug.jks')
// 存储密码
storePassword 'android'
}
}
// 编译类型,详情请看下文。
buildTypes {
debug {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
signingConfig signingConfigs.config // 调用签名
}
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
}
}
}
dependencies {
// 依赖库
}
目标版本的设定值告知Android,应用是为哪一个API级别设计的。大多数情况下,目标版本就是最新发布的Android版本。
什么时候修改目标SDK版本?新发布的SDK版本会改变应用在设备上的显示方式,甚至连操作系统后台运行行为都会受到影响。如果应用开发完成,应确认它在新版本上能否如期那样运行。
降低SDK目标版本可以保证的是,即便在高于目标版本的设备上,应用仍然可以正常运行,且运行行为仍和目标版本一致。这是因为新发布版本中的变化已被忽略。
进入.android
文件夹,可以查看当前已经创建的keystore
。
使用keytool -list -keystore debug.keystore
可以查看keystore
的内容。
生成指令为:keytool -genkey -v -keystore myApp.keystore -alias China -keyalg RSA -keysize 2048 -validity 10000
创建一个用RSA算法加密,大小为2KB,使用SHA256进行签名,10000天的有效期的密钥。
// APP签名
signingConfigs {
config {
// 用户名
keyAlias 'androiddebugkey'
// 在签发过程中使用一个特定密钥的密码
keyPassword 'android'
// 秘钥保存地址
storeFile file('./debug.jks')
// 密钥库文件自身使用的密码
storePassword 'android'
}
}
// 编译类型
buildTypes {
debug {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
signingConfig signingConfigs.config // 调用签名
}
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'
}
}
}
参数 | 说明 |
---|---|
minifyEnabled | 代表在打包的时候app包自动删除无用的资源。如果设置为true,Gradle还会删除无须用到的依赖库。这只会在shrinkResource属性同时设置为true的时候才会生效。 |
shrinkResource | 见上。 |
useProguard | 开启混淆。 |
proguardFiles | 混淆文件规则。 |
你也许遇到过一种情况,当你的APP写到一定程度的时候,你的layout文件和drawable文件会非常的多,这个时候,你可能就想要对资源文件进行分包。
首先,我们可以在app.gradle
增加如下内容:
android {
sourceSets {
main {
// 配置res文件夹
res.srcDirs = [
'src/main/res/layout/activity',
'src/main/res/layout/fragment',
'src/main/res/layout/ui',
'src/main/res/layout',
'src/main/res/drawable/img',
'src/main/res/drawable/xml',
'src/main/res/drawable',
'src/main/res'
]
}
}
}
需要注意的是,目录的顺序需要从最里到最外(即父文件夹放在最后)。
./gradlew
是在Gradle工程下,如果本地配置了gradle环境,可以使用gradle
。一般建议使用Gradle工程目录下的./gradlew
,防止版本问题。
参数 | 说明 |
---|---|
-i | Gradle默认不会输出很多信息,你可以使用-i选项改变日志级别为INFO |
-s | 如果运行时错误发生打印堆栈信息 |
-q | 只打印错误信息 |
-?-h,–help | 打印所有的命令行选项 |
-b,–build-file | Gradle默认执行build.gradle脚本,如果想执行其他脚本可以使用这个命 |
令,比如gradle -b test.gradle | |
–offline | 在离线模式运行build,Gradle只检查本地缓存中的依赖 |
-D,–system-prop | Gradle作为JVM进程运行,你可以提供一个系统属性比如:-Dmyprop=myValue |
-P,–project-prop | 项目属性可以作为你构建脚本的一个变量,你可以传递一个属性值给build脚本,比如:-Pmyprop=myValue |
task | 显示项目中所有可运行的任务 |
properties | 打印项目中所有可配置的属性值 |
检查构建脚本,并显示所有的任务:./gradlew -q task
Gradle支持命令行输入任务名的驼峰简写:
task groupTherapy << {
...
}
task generateTests << {
...
}
这个时候输入./gradlew gT
会报错,因为存在两个简写一致的情况。
参数-x用于排除一个任务:./gradlew groupTherapy -x yayGradle0
开始构建项目:./gradlew build
Gradle包装器,包装器是Gradle的一个核心特性,它允许你的机器不需要安装运行时就能运行Gradle脚本,而且她还能确保build脚本运行在指定版本的Gradle。它会从中央仓库中自动下载Gradle运行时,解压到你的文件系统,然后用来build。终极目标就是创建可靠的、可复用的、与操作系统、系统配置或Gradle版本无关的构建。
task wrapper(type: Wrapper) {
gradleVersion = '1.7'
}
然后执行这个任务:gradle wrapper
。
记住你只需要运行gradle wrapper
一次,以后你就能用wrapper来执行你的任务,下载下来的wrapper文件会被添加到版本控制系统中。如果你的系统中已经安装了Gradle运行时,你就不需要再添加一个gradle wrapper
任务,你可以直接运行gradle wrapper
任务,这个任务会使用你的Gradle当前版本来生成包装文件。
Project实例允许你访问你项目所有的Gradle特性,比如任务的创建和依赖了管理,记住一点当访问你项目的属性和方法时你并不需要显式的使用project变量–Gradle假定你的意思是Project实例,比如setDescription("myProject")
。
外部属性一般存储在键值对中,要添加一个属性,你需要使用ext命名空间。
project.ext.myProp = 'myValue'
ext {
someOtherProp = 123
}
相似的,外部属性可以定义在一个属性文件gradle.properties
中:
exampleProp = myValue
someOtherProp = 455
我们可以在项目中直接访问这两个变量:
assert project.exampleProp == 'myValue'
task printGradleProperty << {
println "Second property: $someOtherProp"
}
动作就是你在任务里面放置构建逻辑的地方,Task接口中提供了两个方法来声明任务的动作:doFirst
和doLast
,当任务执行的时候,定义在闭包里面的动作逻辑就按照顺序执行。
version = '0.1-SNAPSHOT'
task printVersion {
doFirst {
println "Version: $version"
}
doLast {
println "Version: $version"
}
}
下面放上一些比较常见的Android Studio的Gradle使用方式。
在项目根目录中创建gradle.properties,加入以下配置
org.gradle.daemon=true
org.gradle.parallel=true
gradle dependencies
gradle build
gradle build --stacktrace
通过以下命令,可以找出问题所在:
./gradlew processReleaseManifest --stacktrace
gradlew processReleaseManifest --stacktrace