Android Gradle詳解
瞭解Gradle配置對於我們日常開發太重要了,我們要知道為什麼要這樣配置,這樣配置的優缺點,不能盲目。
一,預設配置
1,defaultConfig是Android物件中預設配置,它是一個ProductFlavor。預設配置有包名,版本號,版本名稱等資訊
android{ compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig{ applicationId "com.example.test" minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" //...... } }
2,applicationId是ProductFlavor的一個屬性,用於生成App包名,等同於AndroidManifest.xml檔案中配置的manifest標籤的package屬性值。
3,minSdkVersion是ProductFlavor的一個方法,是App最低支援Android作業系統的版本。
4,targetSdkVersion用於配置基於哪個Android SDK開發。
5,versionCode用於配置App內部版本號,通常用於版本升級。
6,versionName用於配置App的版本名稱,是讓使用者知道當前的版本。
7,配置簽名信息
android { compileSdkVersion 26 buildToolsVersion "26.0.2" signingConfigs{ debug{ storeFile file("test.keystore") storePassword "password" keyAlias "test" keyPassword "password" } release{ storeFile file("test.keystore") storePassword "password" keyAlias "test" keyPassword "password" } } defaultConfig { applicationId "com.example.test" minSdkVersion 15 targetSdkVersion 26 versionCode 1 versionName "1.0.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } }
8,minifyEnabled 開啟程式碼混淆
9,multiDexEnabled 方法超限,啟動拆分多個Dex
10,proguardFiles 混淆配置檔案,可以配置多個
11,shrinkResources 自動清理未使用的資源
12,zipAlignEnabled 整理優化apk
二,Gradle高階用法
1,批量修改apk檔名,AS 3.0之前版本和之後版本寫法不同
apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "26.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } dataBinding { enabled = true } defaultConfig { applicationId "com.example.test" minSdkVersion 15 targetSdkVersion 26 versionCode 1 versionName "1.0.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' zipAlignEnabled true } } applicationVariants.all { variant -> variant.outputs.all { output -> // AS 3.0之後版本 each 改為 all def fileName = "${buildTime()}_release.apk" def outFile = output.outputFile if (outFile != null && outFile.name.endsWith('.apk')) { outputFileName = fileName// AS 3.0之後版本 output.outputFile 改為 outputFileName } } } } def buildTime() { def date = new Date() def formattedDate = date.format('yyyyMMdd') return formattedDate }
2,隱藏簽名檔案資訊
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "26.0.2"
signingConfigs {
def appStoreFile=System.getenv("STORE_FILE")
def appStorePassword=System.getenv("STORE_PASSWORD")
def appKeyAlias=System.getenv("KEY_ALIAS")
def appKeyPassword=System.getenv("KEY_PASSWORD")
release{
storeFile file(appStoreFile)
storePassword appStorePassword
keyAlias appKeyAlias
keyPassword appKeyPassword
}
}
buildTypes {
signingConfig signingConfigs.release
zipAlignEnabled true
}
}
3,動態配置AndroidManifest檔案
Android Gradle提供了manifestPlaceholder佔位符,用來替換AndroidManifest檔案中的內容。比如:我們在用友盟第三方統計需要指定渠道名,這時我們就用到了佔位符。
AndroidManifest檔案中,第三方統計指定渠道名。${UMENG_CHANNEL}就是一個佔位符
<meta-data android:value="${UMENG_CHANNEL}" android:name="UMENG_CHANNEL"/>
build.gradle中定義兩個渠道,xiaomi和baidu,配置manifestPlaceholders。key都是UMENG_CHANNEL,在構建的時候會把AndroidManifest中的UMENG_CHANNEL佔位符替換成manifestPlaceholders中對應的value值
android {
compileSdkVersion 23
buildToolsVersion "26.0.2"
productFlavors{
xiaomi{
manifestPlaceholders.put("UMENG_CHANNEL","xiaomi")
}
baidu{
manifestPlaceholders.put("UMENG_CHANNEL","baidu")
}
}
}
如果渠道非常多,每個渠道都得 指定渠道名,這樣未免太麻煩,不過還有更好的方式。all函式遍歷所有productFlavors,把name作為友盟渠道名。
android {
compileSdkVersion 23
buildToolsVersion "26.0.2"
productFlavors {
xiaomi {
}
baidu {
}
}
productFlavors.all { flavor ->
mManifestPlaceholders.put("UMENG_CHANNEL", name)
}
}
4,自定義BuildConfig
BuildConfig是Gradle構建時自動生成的,我們是如何使用它呢。比如我們打包時有debug和release版本,debug需要顯示log資訊,release版本需要隱藏log資訊,那麼我們打包時不用改程式碼就能知道需要關閉還是開啟log
在build.gradle進行配置 buildConfigField 資料型別 名稱 值
buildTypes {
debug {
buildConfigField "boolean", "type", "true"
}
release {
buildConfigField "boolean", "type", "false"
minifyEnabled true//是否啟動混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
在專案中直接呼叫BuildConfig
if(BuildConfig.type){
//開啟log
}else{
//關閉log
}
5,動態新增資源和圖片
現在有個需求,不同的渠道包app圖示不同,文字也不同。小米渠道顯示的是小米,百度的渠道顯示的是百度。通過resValue可以動態配置string資源,不同的渠道資源不同。resValue 資料型別 名稱 值,呼叫的時候就想呼叫strings.xml中的資源一樣。manifestPlaceholders替換AndroidManifest中的icon,首先在 android:icon="${app_icon}"中定義佔位符app_icon,然後manifestPlaceholders中引用即可
productFlavors {
xiaomi {
resValue 'string', 'name', 'xiaomi'
// 修改 AndroidManifest.xml 裡的icon
manifestPlaceholders = [app_icon: "@mipmap/ic_launcher_xiaomi"]
}
baidu {
resValue 'string', 'name', 'baidu'
// 修改 AndroidManifest.xml 裡的icon
manifestPlaceholders = [app_icon: "@mipmap/ic_launcher_baidu"]
}
}
6,JAVA編譯選項
在我們編譯程式碼的時候,如果對JDK的版本有要求或者是編碼格式有要求,那我們也可以進行配置。
compileOptions {
encoding = 'utf-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}