Gradle使用詳解(三) 之 Android Gradle外掛配置詳解
通上前兩篇博文由淺入深的學習Gradle的基礎和Gradle的Java外掛相關知識後,現在終於到了高潮部分了,讓我們來進一步正式學習Android Gradle外掛。前面提到,Android Gradle外掛是一個基於內建的Java外掛來實現的第三方外掛,它是由google的Android團隊開發的。
分類
Android Gradle外掛根據我們Android工程的屬性分為三類:
外掛名稱 |
id |
描述 |
App |
com.android.application |
App應用工程,它可生成一個執行的apk應用 |
Library |
com.android.library |
Library庫工程,它可生成AAR包 |
Test |
com.android.test |
Test測試工程,用於對App工程或者Library庫工程進行單元測試 |
應該很好理解,像我們之前提到的工程中,有app和mylibrary兩個子工程的情況下,除了Root Project的build.gradle外,其它兩個Child Project的build.gradle的第一行便能看到應用android外掛的程式碼:
\app\build.gradle
apply plugin: 'com.android.application'
mylibrary\build.gradle
apply plugin: 'com.android.library'
配置依賴
前面提到,要應用第三方外掛前,必須先對其進行配置,因為Android Gradle外掛是託管在jcenter庫上,所以在Root Project的build.gradle裡有這樣的程式碼:
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' } }
build.gradle的結構
經過前面的知識學習,現在我們應該可以很容易地看懂在Android Studio新建工程後的Root Project的build.gradle和Child Project的build.gradle的大概意思,我們先列出它們的大至結構:
Root Projec的build.gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
說明:
- buildscript的配置就是上面所說的配置依賴關係
- allprojects的配置我們在《Gradle使用詳解(二) 之 專案結構和初識Java Gradle外掛》中有提過,一般地在Root Project的build.gradle中使用allprojects或subprojects是對Child Project進行統一的抽離公共配置,這樣所有的Child Project的build.gradle就不用重複配置。這裡是配置倉庫。告訴Gradle是要去google庫和jcenter庫搜尋第三方庫。
- task clean是Java外掛內建的Task,同樣也在《Gradle使用詳解(二) 之 專案結構和初識Java Gradle外掛》介紹過,它用於清理構建生成的目錄檔案。
App的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
……
}
buildTypes {
……
}
}
dependencies {
……
}
說明:
- 第一行我們在上面介紹過了,apply plugine就是應用Android Gradle中的App型別外掛
- android{}是Android Gradle工程唯一的一個入口,通過它可以進行自定配置工程引數,我們在下面再對其詳細介紹
- dependencies就是配置依賴關係了,同樣也在《Gradle使用詳解(二) 之 專案結構和初識Java Gradle外掛》介紹過,可以配置依賴第三方庫或者依賴另一個Gradle專案(例如mylibrary)
mylibrary的build.gradle
apply plugin: 'com.android.library'
android {
……
}
dependencies {
……
}
說明:
總體上跟App的build.gradle檔案大同小異,區別在於第一行中應用的是Android Gradle中的Library型別外掛
android{}
Android Gradle工程的配置,都是在android{}中,這是唯一的一個入口。通過它可以對Android Gradle工程進行自定義的配置。示例如下:
android {
compileSdkVersion 26
buildToolVersion "26.0.1"
defaultConfig {
applicationId "com.zyx.myapplication"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
compileSdkVersion
compileSdkVersio是配置Android工程的SDK,或者說是告訴 Gradle 用哪個 Android SDK 版本編譯你的應用。還可以這樣寫成:
android {
compileSdkVersion "android-26"
}
或者
android. compileSdkVersion "android-26"
buildToolVersion
buildToolsVerion表示使用的Android構建工具的版本
defaultConfig{}
defaultConfig是Android物件中的一個配置塊,負責定義所有的預設配置。其裡面配置欄位有很多,我們可以根據不同的情況同時生成多個不同的APK包,比如多渠道打包。裡面欄位有:
applicationId
用於指寫生成的APP的包名,預設情況下是null,若為null,則會在構建的時候從AndroidManifest.xml檔案中配置的manifest標籤的package屬性讀取。
minSdkVerion
用於指寫APP最低支援的Android 系統版本,其對應的值是Android SKD 的API Level。
targetSdkVersion
是 Android 提供向前相容的主要依據,表明是基於哪個Android 版本開發的。也就是說,只要targetSdkVersion 不變,即使APK 安裝在新 Android 系統上,其行為還是保持老的系統上的行為,這樣就保證了系統對老應用的前向相容性。
versionCode
表明APP應用內部版本號,它是一個整數,一般用於APP升級。
verionName
表明APP應用內部版本名稱。
testInstrumentationRunner
用於配置單元測試時使用的Runner,一般情況下使用預設的是android.test.InstrumentationTestRunner即可。
除了上述示例中的欄位外,還有一些比較常用的欄位,如下:
testApplicationId
用於配置測試APP的包名,預設情況下是applicationId + “.test”。一般情況下預設即可。
signingConfig
配置預設的簽名信息,對生成的APP簽名。具體使用可見signingConfigs{}中介紹。
proguardFiles/ proguardFile
proguardFiles是當我們啟用混淆時,ProGuard的配置檔案,它可以同時接受多個配置檔案,因為它的引數是一個可變型別的引數。
proguardFile也是用於配置App proGuard混淆所使用的ProGuard配置檔案,它接收一個檔案作為引數。更多的關於混淆內容,請見buildTypes{}中介紹。
buildTypes{}
buildTypes是一個域物件。它是對構建型別:release、debug等的配置。還可以在buildTypes{}裡新增任意多個需要構建的型別。每一個BuildType還會生成一個SourceSet。上面示例中,release就是一個BuildType。
minifyEnabled(混淆)
用於配置是否啟用Proguard混淆,接愛一個boolean型別的值。程式碼混淆是一個非常有用的功能,它不僅能使APK包size變小,還可以讓反編譯的人不容易看明白我們的原始碼邏輯從而增加分析難度。一般情況下,release模式編譯的版本會啟動混淆功能。因為混淆後無法斷點除錯,所以debug模式下一般是不啟動的。
proguardFiles/ proguardFile
跟defaultConfig中提到的proguardFiles/ proguardFile一樣。
proguardFiles是當我們啟用混淆時,ProGuard的配置檔案,它可以同時接受多個配置檔案,因為它的引數是一個可變型別的引數。
proguardFile也是用於配置App proGuard混淆所使用的ProGuard配置檔案,它接收一個檔案作為引數。
當我們將minifyEnabled設為true,啟動混淆後,還要通過proguardFiles或proguardFile指寫混淆的配置表即可,如上面示例中程式碼:
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
說明:
- getDefaultProguardFile用於指定使用的混淆配置檔案,該檔案路徑於Android SDK安裝目錄下的tools/proguard資料夾下。在該目錄下有兩個Android的Proguard配置檔案:proguard-android.txt和proguard-android-optimize.txt,從名字可以看出,它們一個是無優化,另一個是有做優化的。
- 配置程式碼中,在逗號後是一個檔案,一般地,該檔案位於build.gradle同級目錄中。它就是我們進行不混淆哪些類的配置檔案,注意這裡頭配置的是不混淆白名單,當minifyEnabled設為true後預設是全部混淆的。一般情況下,如果你的程式碼使用到反射的話,都不能進行混淆,就要在此檔案中配置你的不混淆的相關程式碼。一般規則用連起來單詞表示,主要有:
keep 保留,例如keepattributes:表示保留屬性 dont 不要,例如dontwarn:表示不要提示警告 ignore 忽略,例如ignorewarning:表示忽略警告
更多詳細的規則大家可自行上網查詢相關資料,這裡不就作詳情列舉了。
除了上述示例中的欄位外,還有一些比較常用的欄位,如下:
applicationldSuffix
用於配置基於預設applicationId的字尾,比如預設defaultConfig中配置的applicationId為com.zyx.myapplication,若在debug的BuildType中指寫applicationIdSuffix為.debug,那麼構建生成的debug.apk的包名就是com.zyx.myapplication.debug。
debuggable
用於配置是否生成一個可供除錯的apk。一般release中都是為false,而debug中都是為true。
jinDebuggable
跟debuggable類似,用於配置是否生成一個可供除錯Jni(C/C++)程式碼的apk。
multiDexEnabled
用於配置是否啟用自動拆分多個Dex的功能。一般用程式中程式碼太多,超過了65535個方法的時候,拆分多個Dex,接愛一個boolean型別的值。關於突破65535方法限制,我們後面再介紹
zipAlignEnabled
用於配置是否啟用Android 的 zipalign整理優化APK檔案的工具。zipalign能提高系統和應用執行效率,更快地讀寫APK中的資源,降低記憶體的使用。一般情況下,release模式編譯的版本下都會啟動此優化。
shrinkResources
用於配置是否自動清理未使用的資源,預設為false
signingConfig
用於配置APK包的簽名信息。具體使用可見signingConfigs{}中介紹。
signingConfigs{}(APK簽名)
一個APP只有在簽名這後才能被髮布、安裝和使用,簽名是保護APP的方式,它能標記APP的唯一性,防止惡意篡改。一般地我們在開發過程中使用的debug編譯模式時,Android SDK已幫我們打上了一個預設的debug簽名證書(該簽名證書位於$HOME/.android/debug.keystore目錄中),所以我們可以直接除錯安裝在手機上。但是在正式釋出時構建的release模式版本時,我們就要對其進行配置簽名證書了。
配置簽名
關於配置簽名可以在signingConfigs{}中進行,示例如:
android {
……
defaultConfig {
……
}
buildTypes {
……
}
signingConfigs {
releaseConfig {
storeFile rootProject.file("buildkey/mykey.keystore")
storePassword "password"
keyAlias "MyKey"
keyPassword "password"
}
debugConfig { // debug可不配置
storeFile rootProject.file("buildkey/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
}
storeFile
指定簽名證書檔案,接收一個檔案型別
storePassword
配置簽名證書檔案的密碼
keyAlias
配置簽名證書中金鑰別名
keyPassword
配置簽名證書中該金鑰的密碼
應用簽名
上述操作只是配置了簽名證書,要使用它還需要在defaultConfig{}或buildTypes{}中進行signingConfig欄位的指定,正如上面介紹defaultConfig{}或buildTypes{}中所提到的。示例:
android {
……
defaultConfig {
……
signingConfig signingConfigs.releaseConfig
}
buildTypes {
……
}
signingConfigs {
……
}
}
或者針對構建型別分別配置,比如release和debug區分配置:
android {
……
defaultConfig {
……
}
buildTypes {
release {
……
signingConfig signingConfigs.releaseConfig
}
}
signingConfigs {
……
}
}