1. 程式人生 > >Android Gradle詳解

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
}