我們Android項(xiàng)目里會(huì)有Java/Kotlin代碼,Xml文件禀忆,各種圖片音視頻資源文件等蒋情,那么Gradle 就是來(lái)幫我們打包生成 apk 的一個(gè)程序。
Gradle中暂刘,每一個(gè)待編譯的工程都叫一個(gè)Project。每一個(gè)Project在構(gòu)建的時(shí)候都包含一系列的Task。比如一個(gè)Android APK的編譯可能包含:Java源碼編譯Task厚宰、資源編譯Task、JNI編譯Task遂填、lint檢查Task铲觉、打包生成APK的Task、簽名Task等吓坚。一個(gè)Project到底包含多少個(gè)Task撵幽,其實(shí)是由編譯腳本指定的插件決定。插件是什么呢礁击?插件就是用來(lái)定義Task盐杂,并具體執(zhí)行這些Task的東西。
Gradle與前身構(gòu)建工具M(jìn)aven
Gradle拋棄了Maven的基于XML的繁瑣配置哆窿,眾所周知XML的閱讀體驗(yàn)比較差链烈,對(duì)于機(jī)器來(lái)說(shuō)雖然容易識(shí)別,但畢竟是由人去維護(hù)的更耻。取而代之的是Gradle采用了領(lǐng)域特定語(yǔ)言Groovy的配置测垛,大大簡(jiǎn)化了構(gòu)建代碼的行數(shù)。
Gradle 是個(gè)程序秧均、Groovy 是特定領(lǐng)域 DSL 語(yǔ)言
Gradle 是運(yùn)行在 JVM 實(shí)例上的一個(gè)程序食侮,內(nèi)部使用 Groovy 語(yǔ)言
Groovy 是一種 JVM 上的腳本語(yǔ)言,基于 java 擴(kuò)展的動(dòng)態(tài)語(yǔ)言
gradle的生命周期
- initalization初始化階段: 解析整個(gè)工程中所有Project,構(gòu)建所有的Project對(duì)應(yīng)的project對(duì)象目胡,這個(gè)階段主要就是解析setting.gradle文件
- Configuration配置階段:解析所有的projects對(duì)象中的task锯七,構(gòu)建好所有的task拓?fù)鋱D,主要解析各個(gè)project下的build.gradle文件
- Execution執(zhí)行階段:執(zhí)行具體的的task及其依賴task
在項(xiàng)目的build.gradle中監(jiān)聽gradle的生命周期回調(diào):
beforeEvaluate {
println '配置階段開始前的監(jiān)聽回調(diào)'
}
afterEvaluate {
println '配置階段完成以后的回調(diào)'
}
gradle.buildStarted {
println 'build開始的回調(diào)監(jiān)聽'
}
gradle.buildFinished {
println 'build完畢后的回調(diào)監(jiān)聽'
}
gradle.beforeProject {
println 'gradle執(zhí)行前的回調(diào)監(jiān)聽'
}
gradle.afterProject {
println 'gradle執(zhí)行前的回調(diào)監(jiān)聽'
}
gradle方法:
/**
* 獲取所有Project
*/
getAllprojects().eachWithIndex { Project entry, int i ->
}
/**
* 獲取所有子Project
*/
getSubprojects().eachWithIndex { Project entry, int i ->
}
/**
* 配置subproject的所有project(module)
*/
subprojects {
}
/**
* 獲取根Project
*/
getRootProject()
gradle.properties聲明誉己,可在gradle中引用該配置
#dev 開發(fā)環(huán)境
#beta 測(cè)試環(huán)境
#release 正式上線環(huán)境
NET_TYPE=dev
android.useAndroidX=true
android.enableJetifier=true
android.injected.testOnly=false
kotlin.code.style=official
-
gradle倉(cāng)庫(kù)
在項(xiàng)目的根build.gradle文件中眉尸,配置需要從哪里的倉(cāng)庫(kù)下載jar包
repositories {
//構(gòu)建項(xiàng)目時(shí)會(huì)拉取gradle資源,而goole和jcenter在國(guó)內(nèi)的網(wǎng)絡(luò)環(huán)境并不好,容易出現(xiàn)包拉取失敗的問(wèn)題噪猾,那么就可以使用國(guó)內(nèi)阿里的鏡像霉祸。
//repositories里倉(cāng)庫(kù)具有從上到下先后獲取順序
maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
google()
jcenter()
}
Gradle文件配置層級(jí):
- 一個(gè)工程包含一個(gè)setting.gradle文件和一個(gè)build.gradle文件「だ可能有多個(gè)Module丝蹭,每個(gè)Module有自己的一個(gè)build.gradle。
-
setting.gradle: setting文件定義哪些module需要加入到編譯過(guò)程
-
工程的build.gradle:該build文件最終會(huì)被應(yīng)用到所有Module中
-
Gradle Wrapper: 對(duì)Gradle一層包裝坪蚁,便于使用統(tǒng)一Gradle構(gòu)建
gradle-wrapper.jar:具體業(yè)務(wù)邏輯實(shí)現(xiàn)的jar包
gradle-wrapper.properties:配置文件奔穿,包含篇配置信息如下圖:
gradle文件配置示例:
apply plugin: 'com.android.application'
android {
signingConfigs {
config {
keyAlias ''
keyPassword ''
storeFile file('keystore.jks')
storePassword ''
}
}
compileSdkVersion 27
defaultConfig {
applicationId ""
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
multiDexEnabled true
flavorDimensions "versionCode"
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
ndk {
abiFilters 'armeabi-v7a'
}
lintOptions {
abortOnError false
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
debug {
minifyEnabled false
signingConfig signingConfigs.config
}
}
flavorDimensions "tier"
productFlavors {
yingyongbao { dimension "tier" }
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
android.lintOptions { //忽略中英文大小寫
checkReleaseBuilds false
abortOnError false
}
allprojects {
repositories {
mavenCentral()
}
}
repositories {
flatDir {
dir 'libs'
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.jakewharton:butterknife:7.0.1'
}
配置說(shuō)明:
apply plugin:
表明應(yīng)用的插件的類型,工程項(xiàng)目是com.android.application類型敏晤,而Module則是com.android.library
android
這是編譯文件中最大的代碼塊贱田,關(guān)于android 的所有特殊配置都在這里
defaultConfig
程序的默認(rèn)配置
externalNativeBuild
native編譯支持
常用屬性
1.cmake:CMake工具編譯選項(xiàng)。
2.ndkBuild:ndk-build選項(xiàng)嘴脾。
buildTypes
分為release版本和debug版本
常用屬性:
minifyEnabled 是否開啟混淆
shrinkResources 是否去除無(wú)用資源
signingConfigs 簽名配置信息
name:build type的名字
proguardFiles:混淆文件
lintOptions
Lint工具可選項(xiàng)參數(shù)
常用屬性
abortOnError false如果發(fā)現(xiàn)錯(cuò)誤男摧,lint工具是否應(yīng)該退出這個(gè)程序。true表示退出统阿。
productFlavors
項(xiàng)目打包變體配置
flavorDimensions "tier"
productFlavors {
yingyongbao { dimension "tier" }
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
signingConfig
簽名配置信息
signingConfigs {
config {
keyAlias ''
keyPassword ''
storeFile file('keystore.jks')
storePassword ''
}
}
keyAlias 簽名key的別名
keyPassword 簽名key的密碼
storeFile file 簽名key的路徑
storePassword store簽名密碼
v1SigningEnabled:是否使用jar簽名(又名v1簽名)
v2SigningEnabled:是否使用apk簽名(又名v2簽名)
repositories
代碼倉(cāng)庫(kù):Gradle支持從maven中央倉(cāng)庫(kù)和JCenter上獲取構(gòu)件
dependencies
dependencies屬于gradle 的依賴配置彩倚。它定義了當(dāng)前項(xiàng)目需要依賴的其他庫(kù)筹我。
我們?cè)谝脦?kù)的時(shí)候扶平,每個(gè)庫(kù)名稱包含三個(gè)元素:發(fā)布者標(biāo)識(shí):庫(kù)名:版本號(hào)
例如:
implementation 'com.alibaba:fastjson:1.2.8'
如果為implementation 'com.alibaba:fastjson:1.2.+'表示會(huì)使用庫(kù)的最新版本。但是每次編譯都要去做網(wǎng)絡(luò)請(qǐng)求查看是否有新版本導(dǎo)致編譯減慢蔬蕊。
gradle.properties配置
加大可用編譯內(nèi)存:
org.gradle.jvmargs=-Xmx1024m開啟編譯守護(hù)進(jìn)程
org.gradle.daemon=true開啟并行編譯
org.gradle.parallel=true
Gradle Plugin
Gradle是一個(gè)框架结澄,作為框架,它負(fù)責(zé)定義流程和規(guī)則岸夯。而具體的編譯工作則是通過(guò)插件的方式來(lái)完成的麻献。比如編譯Java有Java插件,編譯Groovy有Groovy插件猜扮,編譯Android APP有Android APP插件勉吻,編譯Android Library有Android Library插件。
-
自定義task
task taskName {
//do some things
}
gradle中創(chuàng)建task的兩種方式
task myTask {
println '執(zhí)行myTask'
}
tasks.create(name: 'myTask') {
println '執(zhí)行myTask'
}
定義簡(jiǎn)單task
//定義 task , 名字 hello
task hello {
println "hello world"
}
//定義 task旅赢,名字 hello
task(hello2) {
println "hello world2"
}
//定義 task齿桃,名字 hello3
task ('hello3') {
println "hello world3"
}
task 本質(zhì)上又是由一組被順序執(zhí)行的 Action 對(duì)象構(gòu)成,Action其實(shí)是一段代碼塊煮盼,類似于Java中的方法短纵。
task actionUse {
//在Action 隊(duì)列頭部添加Action
doFirst {
}
//在Action 隊(duì)列尾部添加Action
doLast {
}
//創(chuàng)建一個(gè) Action , 添加到 Action 列表的頭部
doFirst(new Action<Task>() {
@Override
void execute(Task task) {
}
})
}