Gradle 配置詳解
前面我們一起學(xué)習(xí)了 Groovy 語言的語法基礎(chǔ),再由淺入深從 Gradle 的環(huán)境變量配置,到創(chuàng)建一個(gè)簡(jiǎn)單的 Gradle 項(xiàng)目。今天這節(jié)課我們?yōu)榇蠹医榻B一下 Android 項(xiàng)目中 Gradle 的配置。
1. AndroidStudio 項(xiàng)目結(jié)構(gòu)
我們介紹 AndroidStudio 中 Android 項(xiàng)目的 Gradle 配置之前,我們先來看下 AndroidStudio 中 Android 項(xiàng)目的結(jié)構(gòu),我們新建一個(gè)項(xiàng)目結(jié)構(gòu)大致如下圖所示:

我們通過上面的圖片可以看到,Android 項(xiàng)目中跟 Gradle 相關(guān)的主要有 7 個(gè)部分:
- 根目錄下的 build.gradle: 頂級(jí)構(gòu)建文件,配置 Gradle 版本和 Maven 依賴;
- app 目錄下的 build.gralde文件: app 打包和簽名配置,及模塊的依賴;
- gradle 文件夾: 配置 gradel-wrapper;
- setting.gradle 文件: 添加編譯的所有模塊;
- gradle.projects 文件: 項(xiàng)目范圍的梯度設(shè)置,編譯內(nèi)存,Gradle 并發(fā)性等設(shè)置。;
- gradlew 和 gradlew.bat 文件: Gradle 啟動(dòng)腳本文件;
- .gradle 文件夾: 編譯時(shí)的緩存文件夾。
這幾個(gè)部分各自負(fù)責(zé)的功能都不盡相同。下面我們來看下它們具體的功能。
2. 根目錄下的 build.gradle 文件
這個(gè)文件是我們創(chuàng)建 Android 項(xiàng)目的時(shí)候自動(dòng)生成的,它是頂級(jí)構(gòu)建文件,我們可以在其中添加所有子項(xiàng)目/模塊共有的配置選項(xiàng)。我們來看下這個(gè)文件:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//頂級(jí)構(gòu)建文件,您可以在其中添加所有 子項(xiàng)目/modules 共有的配置選項(xiàng)
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
//注意:不要將您的應(yīng)用程序依賴項(xiàng)放在這里; 它們屬于單獨(dú)的模塊 build.gradle 文件
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
以上就是我們每創(chuàng)建一個(gè) Android 項(xiàng)目,項(xiàng)目根目錄下的 build.gradle 文件的代碼,也就是頂級(jí)構(gòu)建文件的代碼。下面來分開講解一下每個(gè)閉包:
2.1 buildscript{} 閉包
首先我們先看下上面的buildscript
閉包,這個(gè)閉包里是配置 Gradle 腳本執(zhí)行所需要的的依賴,分別是對(duì)應(yīng) Maven 倉(cāng)庫(kù)和構(gòu)建工具 Gradle 的版本。
2.1.1 repositories{} 閉包
這個(gè)閉包里面主要是配置遠(yuǎn)程的 Maven 倉(cāng)庫(kù)地址。我們看到里面聲明了jcenter()
和google()
,這兩個(gè)都是 maven 倉(cāng)庫(kù),上面托管了很多開源項(xiàng)目,依賴了這個(gè)我們就可以引用上面的開源項(xiàng)目了。比如 Android 中的 V7,V4 包等。
2.1.2 dependencies{} 閉包
這個(gè)閉包我們直接看,就應(yīng)該能猜到是配置項(xiàng)目構(gòu)建工具 Gradle 的版本的,classpath 就是聲明一個(gè)插件 Gradle來構(gòu)建項(xiàng)目。dependencies
雖然是依賴的意思,但是我們這里需要注意:不能將應(yīng)用程序的依賴放在這里,應(yīng)用程序的依賴在單獨(dú)的build.gradle
里面。
2.2 allprojects{} 閉包
這個(gè)閉包里面的是我們項(xiàng)目運(yùn)行所需要的的依賴,往往和上面的repositories
是相對(duì)應(yīng)的。
buildscript {
repositories { //注釋1
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
//注意:不要將您的應(yīng)用程序依賴項(xiàng)放在這里; 它們屬于單獨(dú)的模塊build.gradle文件
}
}
allprojects {
repositories { //注釋2
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
這里我們需要注意代碼中的注釋1和注釋2處的 repositories
閉包,往往我們添加一個(gè) maven 庫(kù)的依賴時(shí),需要兩個(gè)閉包中都添加一遍。
Tips: 我們添加 Maven 庫(kù)時(shí)可以需要兩個(gè)都添加,比如國(guó)外 Maven 訪問太慢,我們可以加入國(guó)內(nèi)阿里云的 Maven 庫(kù)。
2.3 clean任務(wù)
我們前面講到 Gradle 是基于任務(wù)的,這里的clean
它是一個(gè) Gradle 任務(wù),它繼承自Delete
,我們點(diǎn)擊clean Project
或是執(zhí)行gradle clean
命令的時(shí)候就是在執(zhí)行這個(gè)任務(wù),它的任務(wù)內(nèi)容是刪除build
文件夾下的內(nèi)容。
3. app目錄下的 build.gradle 文件
這個(gè)我們直接看文件內(nèi)容吧:
//注釋1
apply plugin: 'com.android.application'
//注釋2
android {
compileSdkVersion 28
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.bthvi.myuiapplication"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
//注釋3
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
上面的文件就是 app 模塊下的 build.gradle 文件,我們看到主要是分三個(gè)部分,注釋1,注釋2,注釋3分別對(duì)應(yīng)如下三個(gè)語句和閉包:
apply plugin
語句android
閉包dependencies
閉包
3.1 apply plugin
這句是文件中的 第一行,表示的意思是在這個(gè)模塊應(yīng)用一個(gè)插件,插件的值有以下 2 種:
- com.android.application:如果是這個(gè)值,則代表這個(gè)模塊是一個(gè)Android應(yīng)用程序,可以獨(dú)立運(yùn)行,生成
apk
文件。 - com.android.library:如果是這個(gè)值,代表這個(gè)模塊是一個(gè)Android model,不能夠獨(dú)立運(yùn)行,必須依附于application才能運(yùn)行,項(xiàng)目構(gòu)建后生成的是一個(gè)
aar
文件。
Tips:
apply plugin: ‘com.android.application’ 表示這是一個(gè)應(yīng)用程序模塊
apply plugin: ‘com.android.library’ 標(biāo)識(shí)這是一個(gè)模塊module
區(qū)別: 前者可以直接運(yùn)行,后者是需要依附在應(yīng)用程序上運(yùn)行的
3.2 android閉包
這個(gè)閉包主要是配置我們打包的一些信息,包括包名,版本號(hào),版本名稱,混淆配置,簽名信息等。
下面我們?cè)敿?xì)介紹下:
- compileSdkVersion: 設(shè)置編譯時(shí)的 Android 版本。
- buildToolsVersion: 設(shè)置編譯時(shí)構(gòu)建工具的版本。
3.2.1 defaultConfig{}閉包:
這個(gè)閉包里主要是設(shè)置包的一些基本信息,如包名,版本號(hào)等。
- applicationId: 設(shè)置打包后的 APK 的包名。
- minSdkVersion: 設(shè)置 apk 最低的支持 Android 版本,如果手機(jī)的 Android 系統(tǒng)版本低于這個(gè)值,app 一般無法安裝。
- targetSdkVersion: 設(shè)置項(xiàng)目的目標(biāo)版本,表示應(yīng)用程序在該版本上已經(jīng)做過充分的測(cè)試,系統(tǒng)會(huì)為該應(yīng)用啟動(dòng)一些對(duì)應(yīng)該目標(biāo)系統(tǒng)的最新功能特性。
Tips: Android系統(tǒng)的行為變更,只有 targetSdkVersion 的值設(shè)置為大于或等于該手機(jī)系統(tǒng)的 API 版本時(shí),才會(huì)生效。例如,設(shè)置 targetSdkVersion 為 28,對(duì)應(yīng)為 Android 系統(tǒng)版本為 9.0,在 Android 10.0(對(duì)應(yīng) targetSdkVersion 為 29)系統(tǒng)的手機(jī)上,Android 10.0 擁有的新特性[如外存中私有目錄權(quán)限變更等功能]就不會(huì)被啟用。
- versionCode: 設(shè)置 APK 包的版本號(hào),一般情況每次打包都要 +1,否則會(huì)無法覆蓋安裝。
- versionName: 表示版本名稱,展示在 APP 的關(guān)于里面或是應(yīng)用市場(chǎng)上。
- testInstrumentationRunner: 設(shè)置單元測(cè)試,
android.support.test.runner.AndroidJUnitRunner
表明是要使用AndroidJUnitRunner
進(jìn)行單元測(cè)試。
3.2.2 buildTypes{}閉包:
這個(gè)閉包主要是配置我們打包的,一般包含兩個(gè)閉包release
和debug
分別對(duì)應(yīng)的是打Release
包還是Debug
包。所謂Debug
包就是我們直接運(yùn)行的包,這個(gè)包的配置新建項(xiàng)目時(shí)是省略沒有寫的。
buildTypes {
release {// 生產(chǎn)包配置
minifyEnabled true//是否混淆
shrinkResources true//是否啟用未使用資源的收縮
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規(guī)則文件
signingConfig signingConfigs.release//設(shè)置簽名信息
zipAlignEnabled true//是否對(duì)APK包執(zhí)行ZIP對(duì)齊優(yōu)化,減小zip體積
renderscriptOptimLevel 5 //指定RenderScript的編譯優(yōu)化等級(jí),一般設(shè)置為3
}
debug {// 開發(fā)配置
minifyEnabled false//是否混淆
shrinkResources false//是否啟用未使用資源的收縮
signingConfig signingConfigs.release//設(shè)置簽名信息
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規(guī)則文件
zipAlignEnabled true//是否對(duì)APK包執(zhí)行ZIP對(duì)齊優(yōu)化,減小zip體積
renderscriptOptimLevel 5
}
}
從上面的代碼中我們可以看到release
和debug
的配置基本差不多。關(guān)于每個(gè)字段的具體的意義上面注釋中有寫,下面就不多做說明了。我們下面主要看下signingConfig
這個(gè)字段,這個(gè)是設(shè)置 APP 的簽名信息的。
//簽名
signingConfigs {
//你自己的keystore信息
releaseConfig {
storeFile file(rootProject.ext.store_file)
storePassword rootProject.ext.store_password
keyAlias rootProject.ext.key_alias
keyPassword rootProject.ext.key_password
v1SigningEnabled true
v2SigningEnabled true
}
}
Tips: 簽名信息設(shè)置
signingConfig
閉包是在最外層的,也就是和buildTypes
閉包是在同一層級(jí)的。千萬不要把它放在buildTypes
閉包里面。
3.2.3 dependencies 閉包
這個(gè)閉包是項(xiàng)目運(yùn)行所需要的依賴。如我們需要引用的本地 libs 目錄下的第三方的 jar 包或是 aar 包,還可以是 maven 庫(kù)里面的第三方的開源庫(kù) [如 support-v4 support-v7 包等]。
Tips: 這里我們要和最外層的
build.gradle
文件的dependencies
閉包區(qū)分開來。這里的 dependencies 閉包是配置項(xiàng)目運(yùn)行時(shí)引入的第三方庫(kù)。而最晚層的文件中的 dependencies 閉包是配置構(gòu)建項(xiàng)目時(shí)的 Gradle 的版本。
4. gradle文件夾
gradle 文件夾主要是配置 gradle-wrapper 的,我們看到它的目錄下有個(gè)wrapper
目錄,下面有gradle-wrapper.jar
和gradle-wrapper.properties
兩個(gè)文件。

下面我們看下gradle-wrapper.properties
文件的內(nèi)容,我們會(huì)發(fā)現(xiàn)它是配置 Gradle 版本的。看著毫不起眼,但是它卻非常重要,關(guān)于它的詳細(xì)介紹我們下一節(jié)會(huì)做詳細(xì)的講解。
#Sat Nov 09 17:54:23 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
5. setting.gradle 文件
這個(gè)文件其實(shí)非常簡(jiǎn)單,就是配置項(xiàng)目的模塊的,有幾個(gè)模塊就在 setting.gradle 文件里面添加它們的名字就行了。默認(rèn)創(chuàng)建只有app
在里面:
include ':app'
//如果,我們的項(xiàng)目中有person,common,home等模塊時(shí),可以這樣引入
include ':app',':person',':common',':home'
6. gradle.projects 文件
這個(gè)文檔一般我們?cè)谌粘i_發(fā)中不需要去動(dòng)它,這個(gè)文檔主要是項(xiàng)目范圍的梯度設(shè)置,通過 AndroidStudio 配置的漸變?cè)O(shè)置將覆蓋此文件中指定的任何設(shè)置。
# 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.
org.gradle.jvmargs=-Xmx1024m
# 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
通過上面的代碼我們看到主要有一句沒有注釋,第 9 行,這句的作用就是設(shè)置運(yùn)行時(shí)的最大內(nèi)存。
Tips: 這里分享一個(gè)經(jīng)驗(yàn),如果你的電腦編譯項(xiàng)目耗時(shí)比較久,我們可以修改這個(gè)文件的配置,適當(dāng)增加編譯時(shí)的內(nèi)存,使 Gradle 獨(dú)立運(yùn)行。筆者親測(cè)有效:第11、12行。
# 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.
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# 提高AndroidStudio的并發(fā)性,使Gradle獨(dú)立運(yùn)行。
org.gradle.parallel=true
org.gradle.daemon=true
7. gradlew 和 gradlew.bat 文件
這兩個(gè)文件其實(shí)就是 Gradle 啟動(dòng)的腳本文件,我們可以使用gradlew
命令來打包相當(dāng)于gradle
命令。關(guān)于gradle
的命令我們后面有一節(jié)專門介紹。這節(jié)我們看下這兩個(gè)文件的區(qū)別,以及怎么使用gradlew
命令。
下面我們看看這兩個(gè)文件的前面幾行:
gradlew 文件
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
gradlew.bat 文件
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
通過上面的注釋我們可以看到,原來這兩個(gè)文件的作用是你一樣的,都是 Gradle 啟動(dòng)的腳本文件,不過gradlew
文件是 Linux 系統(tǒng)或是 Unix 系統(tǒng)的腳本文件,而gradlew.bat
是 Windows 系統(tǒng)的腳本文件。
使用 gradlew 命令,以 clean 命令為例,我們只需要在 AndroidStudio下輸入如下命令:
//Windows系統(tǒng)
gradlew clean
//Linux系統(tǒng)或是Mac系統(tǒng)
./gradlew clean
Tips: 我們可能在 MAC 或是 Linux 系統(tǒng)中遇到
bash: ./gradlew: Permission denied
這個(gè)錯(cuò)誤,這是因?yàn)闆]有權(quán)限。我們只需要執(zhí)行chmod +x gradlew
這個(gè)命令后,再執(zhí)行./gradlew clean
命令就 OK 了。
8. .gradle 文件夾
這個(gè)文件其實(shí)我們不用太在意它,這個(gè)文件夾是項(xiàng)目構(gòu)建的一個(gè)緩存的目錄。只要我們打開一個(gè) Android 項(xiàng)目,它就會(huì)生成這個(gè)文件夾。是一個(gè)臨時(shí)的文件夾。
9. 小結(jié)
本節(jié)我們主要為大家介紹了 AndroidStudio 中 Android 項(xiàng)目的結(jié)構(gòu),及相關(guān) Gradle 知識(shí)的詳解。我們回顧一下前面所說的 7 個(gè)文件的作用:
- 根目錄下的 build.gradle: 頂級(jí)構(gòu)建文件,配置 Gradle 版本和 Maven 依賴;
- app 目錄下的 build.gralde文件: app 打包和簽名配置,及模塊的依賴;
- gradle 文件夾: 配置 gradel-wrapper;
- setting.gradle 文件: 添加編譯的所有模塊;
- gradle.projects 文件: 項(xiàng)目范圍的梯度設(shè)置,編譯內(nèi)存,Gradle 并發(fā)性等設(shè)置;
- gradlew 和 gradlew.bat 文件: Gradle 啟動(dòng)腳本文件;
- .gradle 文件夾: 編譯時(shí)的緩存文件夾。