Android面向复习—-通俗理解Android中的Gradle
1. Gradle是什么?
Gradle是一种构建工具,它可以帮你管理项目中的差异、依赖、编译、打包、部署等。它并不是一种语言,不能实现软件中的任何实际功能。
2. Android工程中Gradle相关文件及功能
在一个安卓项目中,主要包括以下几个部分Gradle相关的文件(夹)
- Top-level Gradle:用于配置所有 Module 的属性
- Moudle-level Gradle: 配置独立 Moudle 的属性
- Gradle Wrapper: 用于统一编译环境, 一般供 CI 使用
3. Top-level Gradle介绍
-
buildscript
简单来说,buildscript就是运行构建脚本所需要用到的依赖的classpath,其内部会把configuration closure传递给ScriptHandler(不用关心它是什么),然后实现设置dependencies(构建脚本运行所依赖的文件)和repositories(依赖文件的查找位置)
一般而言,script block都写在开头,声明这个脚本本身所需的依赖// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
} -
allprojects
这个configuration closure里的内容会被设置为当前project以及其所有sub-project中依赖文件的查找路径。
allprojects {
repositories {
jcenter()
}
} -
task clean
此处定义了一个新的task,叫做clean,其类型是Delete。实际上,Android plugin内置了clean方法,该方法位于module中,Moudle中内置的clean方法只会清理Module中的文件并删除Module中的build目录,但是工程根目录下的build文件是没人清理的,所以,在这里定义clean的方法,删除项目目录下的build文件夹。
task clean(type: Delete) {
delete rootProject.buildDir
} -
settings.gradle
它是用来管理sub-project的,这里配置了该project所包含的需要编译的子项目,在编译时gradle会按照配置递归编译子项目。
include ':app', ':library'
4. Modlue-Level Build Script
-
第一行
模块级的script用于模块的编译过程,Android中可能用到的一共有3种
- Android:对应
com.android.application
,编译结果是apk - Android Libary:对应
com.android.libary
编译结果为aar - JavaLibary: 对应的
java
编译结果为jar
apply plugin: 'com.android.application'
- Android:对应
-
全集的build.gradle
apply plugin: 'com.android.application'
android{
/**设置编译 sdk 和编译工具的版本*/
compileSdkVersion 24
buildToolsVersion "24.0.3"
/**
*关于签名, 请参考 google 官方文档: <a href="https://developer.android.com/studio/publish/app-signing.html#debug-mode">Sign
*Your App</a>
**/
signingConfigs {
/**
* As 会自动帮我们使用 debug certificate 进行签名. 这个 debug certificate 每次安装 As 都会变,
* 因此不适合作为发布之用.
*/
debug {
}
/**
* 由于 Module-level Build Script(本文件) 也要放在 VCS 中管理, 所以不将密码等信息写在这里.
* 一般的做法是: 在本机设置环境变量, 然后通过下面代码中演示的这种方式读取.
* 当然, 最佳实践也指导我们将 `gradle.properties` <strong><em>排除</em>在 VCS 之外</strong>,
* 此时, 也在该文件中将密码设置为变量, 然后在此读取使用.
*/
release {
storeFile file("$System.env.STORE_FILE")
storePassword "$System.env.STORE_PASSWORD"
keyAlias "$System.env.KEY_ALIAS"
keyPassword "$System.env.KEY_PASSWORD"
}
}
/**
*为所有的 build variants 设置默认的值. 关于 build variant, 我们后面会用一张图片说明
*/
defaultConfig{
applicationId "com.walfud.myapplication"
minSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
/**
*type 默认会有 debug 和 release. 不管你写不写都如此.
*通常, 我们在 debug 中保留默认值, release 中开启混淆, 并使用私有的签名
*/
buildTypes{
debug{
//使用默认值
}
release{
//混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
//签名
signingConfig signingConfigs.release
}
}
/**
*flavor 强调的是不同的版本, 比如付费版和免费版.
*在国内, 这个字段更多被用于区分不同的渠道, 即 360 渠道, 小米渠道等等.
*/
productFlavors{
m360 {}
xiaomi{}
}
/**
*这个选项基本不用.
*<a href="http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits">官方说</a>:
*使用 splits 可以比使用 flavor 更加有效创建多 apk.
*目前而言, 仅支持 Density 和 ABIs 这两个分类.
*/
splits{
//按屏幕尺寸
density{
enable true
//默认包含全部分辨率, 这里是剔除一些我们不要的
exclude "ldpi",
"mdpi",
"xxxhdpi",
"400dpi",
"560dpi",
"tvdpi"
}
//按架构
abi{
enable true
//使用 `reset()` 后, 我们就相当于不包含任何架构,
//这种情况下我们就可以通过 `include` 指定想要使用的架构
reset()
include'x86',armeabi-v7a'
universalApk true
//是否同时生成一个包含全部 Architecture 的包
}
}
}
/**
* 这个项目的依赖*/
dependencies{
/**
*fileTree` 导入 libs 目录下的所有 jar 文件
*/
compile
fileTree(dir: 'libs',include: ['*.jar'])
/**
*想导入本地 aar, 首先需要指明本地 aar 的位置, 如下 `repositories` 中所示, 我们把 aar 放在了
*Module-level 的 libs 目录下. 然后引用这个文件即可.
*/
compile(name: 'components', ext: 'aar')
}
/**
* 配置了去哪里查找这个模块依赖文件
*/
repositories{
flatDir
{ dirs
'libs'
}
} -
Build Variant
简单的说, 就是为了不同的渠道或者版本自动生成相应的 apk. 其算法是 buildType * productFlavor * density * abi 做一个笛卡尔积.