一、Gradle簡介
1、Gradle是什麼?
Gradle是一種專案自動化構建工具,基於Groovy語言來宣告專案設定,同時支援kotlin檔案xxx.gradle.kts作為DSL(Domain Specified Language)。
2、對比其他構建工具
對與最直接的比較就是Gradle和Maven的比較,還有Ant,不過目前基本沒有什麼基於Ant構建的專案這裡就不提了。
首先Gradle的簡易性比Maven要好的多。Groovy語法的書寫和可讀性要比Maven中的Xml方便很多。
其次,Gradle中自定義功能要比Maven中方便很多。在Gradle中自定義Task即可,在Maven要寫外掛來實現。
3、Gradle的安裝與配置
安裝、配置環境變數、測試安裝結果。具體參考Gradle官網gradle.org/install/
二、Gradle專案目錄結構
1、基本gradle專案
新建build.gradle檔案,進入該目錄命令列執行gradle build
便可生成.gradle隱藏檔案。這就是基本的gradle專案。
命令列執行
gradle wrapper
生成如下結構,該命令是同統一不同開發者使用相同的Gradle構建版本進行構建。如使用多專案構建還需使用setting.gradle等構建指令碼,具體在android中的gradle進行介紹。
2、android studio中的gradle目錄結構
這裡需要一點。在android studio中,Gradle和Android獨立執行,這意味著Android的構建並不依賴與IDE,可以配合Gradle單獨完成專案的構建。android studio只不過是幫助我們生成了一個目錄結構並介面化的處理Gradle中的任務。
我們先看一下新建andorid專案的目錄結構
三、構建配置檔案解釋
1、settings.gradle
該檔案為gradle設定檔案,位於專案根目錄,配置專案的多模組構建,include ':app', ':example_module'
表示使用同級目錄中的app模組、example_module模組。也可以具體制定模組路徑。如下使用
include ':app'
include ':example_module'
project(':example_module').projectDir = new File(rootDir,'example/example_module')
複製程式碼
2、gradle.properties,local.properties
該檔案為專案屬性檔案,可用於儲存key-value資源供專案使用。
gradle.properties中android studio會自動幫我們建立org.gradle.jvmargs=-Xmx1536m
該屬性為Gradle後臺程式的最大堆大小,最小為1536m,我們也可以自定義修改該值org.gradle.jvmargs = -Xmx2048m
。
我們也可以配置其他屬性,如org.gradle.caching=true
讓gralde配置使用快取,減少少編譯時間。
其實還有很多屬性可以配置具體可以看Gradle官網中的Build Environmentdocs.gradle.org/current/use…
local.properties中會填寫本地的SDK、NDK路徑,多人開發一般要加入.gitignore。
3、根目錄build.gradle
專案級build.gradle 檔案位於專案根目錄,用於定義適用於專案中所有模組的構建配置。
/**
* buildscript{}宣告工程所需要的依賴,如在module中需要引用的外掛
* 比如要在module中引用 apply :'com.android.application',
* 需要在這裡加入依賴 classpath 'com.android.tools.build:gradle:3.1.4'
*/
buildscript {
/**
* repositories{}宣告瞭工程所需要的依賴庫,供下面dependencies下載
* 低版本gradle需要將google()改為
* maven { url 'https://maven.google.com/' }
*/
repositories {
google()
jcenter()
}
/**
* dependencies{}宣告瞭具體的依賴,使用[group]:[name]:[version]形式
*/
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
}
}
/**
* allprojects{}定義了專案中所有module的配置
* 此處所有module的遠端倉庫都新增了google()和jcenter()
*/
allprojects {
repositories {
google()
jcenter()
}
}
/**
* 此處就是gradle中的一個task,名稱為clean,
* 使用Groovy語言實現,完全相容java,
* 可以跟進delete方法,內部就是一個用java實現的遞迴刪除方法
*/
task clean(type: Delete) {
delete rootProject.buildDir
}
複製程式碼
4、module中build.gradle
模組級build.gradle檔案位於每個module資料夾中,用於配置適用於其所在模組的構建設定,如自定義打包設定、引入模組內的依賴等。
/**
* 引入所需外掛 此處使用‘com.android.application’
* 提供了android {} 配置的可用性,使用者構建android專案
*/
apply plugin: 'com.android.application'
/**
* android{}部分是根據com.android.application來配置的屬性,
* 包含了android專案配置的必要資訊
*/
android {
/**
* compileSdkVersion 是gradle中用於構建使用的版本,
* 可以使用該版本及以下的API特性
*
* buildToolsVersion 使用android SDK build tools的版本
*/
compileSdkVersion 26
buildToolsVersion "28.0.3"
/**
* 基本配置,某些配置會覆蓋manifest中的配置
*/
defaultConfig {
/**
* applicationId ,編譯打包時會將該處配置覆蓋到manifest中
*/
applicationId 'com.example.myapp'
// 定義最小執行的android版本
minSdkVersion 15
// 指定應用程式的API級別用來測試。
targetSdkVersion 26
// app的版本號,某些手機上安裝應用會進行校驗,不能降級安裝
versionCode 1
// app的版本名稱,一般使用三位數控制“1.1.0”
versionName "1.0"
}
/**
* buildTypes {} 宣告瞭構建型別,預設包含了debug,release
* 也可以增加自定義的構建型別
*/
buildTypes {
/**
* 配置當構建型別為release時的選項,如是否開啟混淆,及混淆規則檔案
* 也可以增加構建配置,如增加簽名檔案的相關配置
*/
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
/**
* productFlavors {}宣告瞭不同的特色版本。
* 這裡的配置可以覆蓋defaultConfig {}中的配置
* 比如說這裡的例子配置了一個付費的版本和一個免費的版本
* 使用了不同的applicationId使兩個專案可以同時執行在一個手機上
*/
productFlavors {
free {
applicationId 'com.example.myapp.free'
}
paid {
applicationId 'com.example.myapp.paid'
}
}
/**
* 多APK構建,根據螢幕的dpi或者系統的ABI來進行生成不同的apk
* 使用不多,這裡不做重點介紹
*/
splits {
// Screen density split settings
density {
// Enable or disable the density split mechanism
enable false
// Exclude these densities from splits
exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
}
}
}
/**
* dependencies {} 宣告的module級別的依賴來實現對其他專案的呼叫
*/
dependencies {
implementation project(":lib")
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
複製程式碼
四、對於提高編譯速度的建議
1、使用最新的Android gradle外掛
Google tools team一直致力於提高android studio的編譯速度,使用最新的gradle外掛可以搞編譯速度
在Android Gradle Plugin 3.0.0後,google推出了新的依賴方式,並強制要求廢棄老的依賴方式,將原有的compile閉包方法,拆分成implementation,api以明確專案的依賴關係。
其中implementation僅對當前module依賴有效,api同compile,存在依賴的傳遞性。錯誤的使用則會導致依賴被載入兩次,增加編譯時間。
更多3.0.0之後的特性可以參考官方文件中的Dependency configurations部分developer.android.com/studio/buil…
- compile 'com.android.support:appcompat-v7:27.1.1'
+ implementation 'com.android.support:appcompat-v7:27.1.1'
複製程式碼
2、避免使用multidex
當minSdkVersion為21以下的時候的時候(不包含21),則編譯時間會大大增加。我們可以通過定製開發版本編譯minSdkVersion為21來提高開發效率,具體配置如下:
android {
defaultConfig {
...
multiDexEnabled true
}
productFlavors {
dev {
minSdkVersion 21
}
prod {
minSdkVersion your_minSDKVersion
}
}
...
}
複製程式碼
3、避免使用multi-APK(不常使用)
當需要針對不同的ABI或dpi做支援,使用spilts{}對工程生成不同apk時可以使用該方法。
在開發除錯的時候,關閉splits功能,具體配置如下:
android {
...
if (project.hasProperty(‘devBuild’)){
splits.abi.enable = false
splits.density.enable = false
}
...
}
複製程式碼
使用命令列構建時使用這個命令:
./gradlew assembleDevelopmentDebug -PdevBuild
// gradlew assembleDevelopmentDebug -PdevBuild
複製程式碼
當使用Android Studio構建可做以下配置:
開啟Preferences -> Build, Execution, Deployment -> Compiler,再Command-line選項後填寫-PdevBuild,如下圖所示:
4、減少打包的資原始檔
在我們進行開發除錯的時候,沒有必要對所有的資原始檔進行編譯,通常只選擇一種可以減少編譯時間,具體配置如下:
android{
...
productFlavors {
development {
minSdkVersion 21
//only package english translations, and xxhdpi resources
resConfigs (“en”, “xxhdpi”)
}
}
...
}
複製程式碼
5、禁用PNG壓縮
android構建的時候預設開啟了PNG壓縮,在開發除錯時,可以將PNG壓縮關閉,具體配置如下:
android {
...
if (project.hasProperty(‘devBuild’)){
aaptOptions.cruncherEnabled = false
}
...
}
複製程式碼
6、使用Instant run
andorid studio 3.0之後對instant run進行了很大的優化,之前的版本出現過更新的程式碼沒有執行到手機上,所以一直關閉著。現在可以嘗試使用。
7、不在gradle中定義動態變數
在開發除錯的情況下,不要使用動態定義
// def buildDateTime = new Date().format(‘yyMMddHHmm’).toInteger()
def buildDateTime = project.hasProperty(‘devBuild’) ? 100 : new Date().format(‘yyMMddHHmm’).toInteger()
android {
defaultConfig {
versionCode buildDateTime
}
}
複製程式碼
8、不要使用動態依賴版本
專案在構建的過程中具有不確定性,可能因為網路問題導致編譯時間過長或編譯失敗。並且Gradle會每24小時檢查一次新的依賴版本從而增加依賴解析時間。
不要使用下面的依賴方式
// 錯誤的示範
implementation 'com.appadhoc:abtest:latest'
implementation 'com.android.support:appcompat-v7:27+'
複製程式碼
9、對Gradle後臺程式的最大堆大小的分配
分配更大的記憶體可能會對大的專案的構建有時間上的減少,具體還要看電腦的配置等其他因素,具體可以參考gradle官網 Configuring JVM memory:docs.gradle.org/current/use…
新版本配置時在gradle.properties中配置
org.gradle.jvmargs=-Xmx1536m
複製程式碼
不要在使用老版本的在build.gradle中配置
dexOptions {
javaMaxHeapSize = ‘4g’
}
複製程式碼
10、使用Gradle快取
Gradle快取是Gradle 3.5的新特性,當快取開啟時,Gradle將快取並重用之前構建的結果。具體在gradle.properties中增加如下配置:
org.gradle.caching=true
複製程式碼
以上幾點出自google 2017 I/O大會,具體可參看會議視訊 www.youtube.com/watch?v=7ll…
11、針對專案構建時間具體進行優化
針對每個專案的構建呢,具體的優化也不會相同,我們可以將我們專案的具體構建時間輸出成文件,具體分析哪塊的構建時間過長,來針對性的優化。具體命令如下:
gradlew --profile --recompile-scripts --offline --rerun-tasks assembleFlavorDebug
複製程式碼
- --profile:啟用分析
- --recompile-scripts:在繞過快取時強制重新編譯指令碼。
- --offline:禁止 Gradle 提取線上依賴項。這樣可以確保 Gradle 在嘗試更新依賴項時引起的任何延遲都不會干擾您的分析資料。您應當已將專案構建一次,以便確保 Gradle 已經下載和快取您的依賴項。
- --rerun-tasks:強制 Gradle 重新執行所有任務並忽略任何任務優化。 構建完成後,在_project-root_/build/reports/profile/ 目錄下使用瀏覽器開啟生成的profile-timestamp.html即可看到具體的構建時間報告。
五、總結
通過上面的文章,我們就已經瞭解瞭如何配置gradle來對android專案進行構建,以及對專案構建進行部分優化,但是我們對於原理部分還所知甚少,比如為什麼可以在build.gradle中定義android{}這部分程式碼,為什麼這裡就可以實現對專案的配置,本著知其然,知其所以然的態度,我們要繼續對gradle進行探索,瞭解groovy語法,瞭解gradle中的task,及使用自定義構建功能。
相關連線
Android中的Gradle之玩轉自定義功能
參考文件:
andorid官方文件——配置構建 developer.android.com/studio/buil…
gradle官方文件——Building Android Apps guides.gradle.org/building-an…
Google I/O中提到的提高Android studio的編譯速度的幾個建議 blog.csdn.net/sd19871122/…