史上最全Android build.gradle配置詳解

Android Studio是採用gradle來構建項目的,gradle是基於groovy語言的,若是隻是用它構建普通Android項目的話,是能夠不去學groovy的。當咱們建立一個Android項目時會包含兩個Android build.gradle配置詳解文件,以下圖:javascript

1、Project的build.gradle文件:

對應的build.gradle代碼以下:php

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {//這裏是gradle腳本執行所需依賴,分別是對應的maven庫和插件

    repositories {
        google()//從Android Studio3.0後新增了google()配置,能夠引用google上的開源項目
        jcenter()//是一個相似於github的代碼託管倉庫,聲明瞭jcenter()配置,能夠輕鬆引用 jcenter上的開源項目
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'////此處是android的插件gradle,gradle是一個強大的項目構建工具

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {//這裏是項目自己須要的依賴,好比項目所需的maven庫
    repositories {
        google()
        jcenter()
    }
}

// 運行gradle clean時,執行此處定義的task任務。
// 該任務繼承自Delete,刪除根目錄中的build目錄。
// 至關於執行Delete.delete(rootProject.buildDir)。
// gradle使用groovy語言,調用method時能夠不用加()。
task clean(type: Delete) {
    delete rootProject.buildDir
}

複製代碼
  • buildscript{}閉包裏是gradle腳本執行所需依賴,分別是對應的maven庫和插件。
  • allprojects{}閉包裏是項目自己須要的依賴,好比項目所需的maven庫。
  • task clean(type: Delete){}是運行gradle clean時,執行此處定義的task任務,該任務繼承自Delete,刪除根目錄中的build目錄。其中buildscript包含repositories閉包和dependencies閉包。

repositories{}閉包:配置遠程倉庫

該閉包中聲明瞭jcenter()和google()的配置,其中jcenter是一個代碼託管倉庫,上面託管了不少Android開源項目,在這裏配置了jcenter後咱們能夠在項目中方便引用jcenter上的開源項目,從Android Studio3.0後新增了google()配置,能夠引用google上的開源項目。java

dependencies{}閉包:配置構建工具

該閉包使用classpath聲明瞭一個Gradle插件,因爲Gradle並不僅是用來構建Android項目,所以此處引入相關插件來構建Android項目,其中'3.0.0'爲該插件的版本號,能夠根據最新的版本號來調整。android

2、Module的build.gradle文件:

從文件內容能夠看出,主要分爲三大部分,以下圖所示:c++

一、apply plugin:

// 聲明是Android程序,
//com.android.application 表示這是一個應用程序模塊
//com.android.library 標識這是一個庫模塊
//而這區別:前者能夠直接運行,後着是依附別的應用程序運行
apply plugin: 'com.android.application'

複製代碼

文件中第一行使用apply plugin表示應用了一個插件,該插件通常有兩種值可選:git

  • 'com.android.application',表示該模塊爲應用程序模塊,能夠直接運行,打包獲得的是.apk文件
  • 'com.android.library',表示該模塊爲庫模塊,只能做爲代碼庫依附於別的應用程序模塊來運行,打包獲得的是.aar文件

二、android{}閉包:

這個閉包主要爲了配置項目構建的各類屬性:github

2.一、添加signingConfigs{}閉包:
signingConfigs {// 自動化打包配置
        release {// 線上環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.keystore')
            storePassword '123456'
        }
        debug {// 開發環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.keystore')
            storePassword '123456'
        }
    }

複製代碼

能夠手動添加簽名配置,也能夠經過Project Structure 選中app,點擊Singing添加,具體步驟以下圖所示:windows

簽名配置完成後能夠方便帶簽名打包,在module的Build Variants中有兩個Type,分別是debug和release,能夠選擇任意一個類型進行打包,而且他們會利用各自配置的Key進行打包,執行 Run app或者Build->Build apk就會自動在module name/app/build/outputs/apk路徑下生成Apk文件。另外一種打包方式是Build->Generate Signed APK填寫簽名信息生成Apk。api

2.二、compileSdkVersion:設置編譯時用的Android版本
2.三、buildToolsVersion:設置編譯時使用的構建工具的版本,Android Studio3.0後去除此項配置
2.四、defaultConfig{}閉包:
compileSdkVersion 27//設置編譯時用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//項目的包名
        minSdkVersion 16//項目最低兼容的版本
        targetSdkVersion 27//項目的目標版本
        versionCode 1//版本號
        versionName "1.0"//版本名稱
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//代表要使用AndroidJUnitRunner進行單元測試
    }
複製代碼
  • applicationId:指定了項目的包名。
  • minSdkVersion:指定項目最低兼容的版本,若是設備小於這個版本或者大於maxSdkVersion(通常不用)將沒法安裝這個應用,這裏指定爲16,表示最低兼容到Android 4.1系統。
  • targetSdkVersion:指定項目的目標版本,表示在該目標版本上已經作過充分測試,系統會爲該應用啓動一些對應該目標系統的最新功能特性,Android系統平臺的行爲變動,只有targetSdkVersion的屬性值被設置爲大於或等於該系統平臺的API版本時,纔會生效。例如,若指定targetSdkVersion值爲22,則表示該程序最高只在Android5.1版本上作過充分測試,在Android6.0系統上(對應targetSdkVersion爲23)擁有的新特性如系統運行時權限等功能就不會被啓用。
  • versionCode:表示版本號,通常每次打包上線時該值只能增長,打包後看不見。
  • versionName:表示版本名稱,展現在應用市場上。
  • testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"代表要使用AndroidJUnitRunner進行單元測試。
2.五、 buildTypes{}閉包:

這個閉包主要指定生成安裝文件的主要配置,通常包含兩個子閉包,一個是debug閉包,用於指定生成測試版安裝文件的配置,能夠忽略不寫;另外一個是release閉包,用於指定生成正式版安裝文件的配置。二者能配置的參數相同,最大的區別默認屬性配置不同,兩種模式支持的屬性配置以下圖:緩存

buildTypes {// 生產/測試環境配置
        release {// 生產環境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日誌
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則文件
            signingConfig signingConfigs.release//設置簽名信息
            pseudoLocalesEnabled false//是否在APK中生成僞語言環境,幫助國際化的東西,通常使用的很少
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減少zip體積,增長運行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
            versionNameSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
        }
        debug {// 測試環境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日誌
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則文件
            signingConfig signingConfigs.debug//設置簽名信息
            debuggable false//是否支持斷點調試
            jniDebuggable false//是否能夠調試NDK代碼
            renderscriptDebuggable false//是否開啓渲染腳本就是一些c寫的渲染方法
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減少zip體積,增長運行效率
            pseudoLocalesEnabled false//是否在APK中生成僞語言環境,幫助國際化的東西,通常使用的很少
            applicationIdSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
            versionNameSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
        }
    }
複製代碼
release{}閉包和debug{}閉包二者能配置的參數相同,最大的區別默認屬性配置不同:
  • minifyEnabled:代表是否對代碼進行混淆,true表示對代碼進行混淆,false表示對代碼不進行混淆,默認的是false。
  • proguardFiles:指定混淆的規則文件,這裏指定了proguard-android.txt文件和proguard-rules.pro文件兩個文件,proguard-android.txt文件爲默認的混淆文件,裏面定義了一些通用的混淆規則。proguard-rules.pro文件位於當前項目的根目錄下,能夠在該文件中定義一些項目特有的混淆規則。
  • buildConfigField:用於解決Beta版本服務和Release版本服務地址不一樣或者一些Log打印需求控制的。例如:配置buildConfigField("boolean", "LOG_DEBUG", "true"),這個方法接收三個非空的參數,第一個:肯定值的類型,第二個:指定key的名字,第三個:傳值,調用的時候BuildConfig.LOG_DEBUG便可調用。
  • debuggable:表示是否支持斷點調試,release默認爲false,debug默認爲true。
  • jniDebuggable:表示是否能夠調試NDK代碼,使用lldb進行c和c++代碼調試,release默認爲false
  • signingConfig:設置簽名信息,經過signingConfigs.release或者signingConfigs.debug,配置相應的簽名,可是添加此配置前必須先添加signingConfigs閉包,添加相應的簽名信息。
  • renderscriptDebuggable:表示是否開啓渲染腳本就是一些c寫的渲染方法,默認爲false。
  • renderscriptOptimLevel:表示渲染等級,默認是3。
  • pseudoLocalesEnabled:是否在APK中生成僞語言環境,幫助國際化的東西,通常使用的很少。
  • applicationIdSuffix:和defaultConfig中配置是一的,這裏是在applicationId 中添加了一個後綴,通常使用的很少。
  • versionNameSuffix:表示添加版本名稱的後綴,通常使用的很少。
  • zipAlignEnabled:表示是否對APK包執行ZIP對齊優化,減少zip體積,增長運行效率,release和debug默認都爲true。
2.六、sourceSets{}閉包:配置目錄指向
sourceSets {//目錄指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib庫目錄
        }
    }
複製代碼

配置 jniLibs.srcDirs = ['libs'],能夠在Android studio的Android視圖下生成jniLibs文件夾,能夠方便咱們存放jar包和庫文件,其中Android視圖下的jniLibs和project視圖下的libs指向同一文件夾(app→libs),以下圖所示:

2.七、packagingOptions{}閉包:打包時的相關配置

當項目中依賴的第三方庫愈來愈多時,有可能會出現兩個依賴庫中存在同一個(名稱)文件。若是這樣,Gradle在打包時就會提示錯誤(警告)。那麼就能夠根據提示,而後使用如下方法將重複的文件剔除,比較經常使用的是經過exclude去除重複的文件,例如:

packagingOptions{
        //pickFirsts作用是 當有重複文件時 打包會報錯 這樣配置會使用第一個匹配的文件打包進入apk
        // 表示當apk中有重複的META-INF目錄下有重複的LICENSE文件時 只用第一個 這樣打包就不會報錯
        pickFirsts = ['META-INF/LICENSE']

        //merges何須 當出現重複文件時 合併重複的文件 而後打包入apk
        //這個是有默認值得 merges = [] 這樣會把默默認值去掉 因此咱們用下面這種方式 在默認值後添加
        merge 'META-INF/LICENSE'

        //這個是在同時使用butterknife、dagger2作的一個處理。同理,遇到相似的問題,只要根據gradle的提示,作相似處理便可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
複製代碼
2.八、productFlavors{}閉包:多個渠道配置

這個配置是常常會使用到的,一般在適配多個渠道的時候,須要爲特定的渠道作部分特殊的處理,好比設置不一樣的包名、應用名等。場景:當咱們使用友盟統計時,一般須要設置一個渠道ID,那麼咱們就能夠利用productFlavors來生成對應渠道信息的包,如:

android {  
    productFlavors {
        wandoujia {
            //豌豆莢渠道包配置
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
            //manifestPlaceholders的使用在後續章節(AndroidManifest裏的佔位符)中介紹
        }
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
            applicationId "com.wiky.gradle.xiaomi" //配置包名

        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        //...
    }  
}
複製代碼

固然也有更簡潔的方式:

android {  
    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
       //...
    }  

    productFlavors.all { 
        //批量修改,相似一個循序遍歷
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] 
    }
}
複製代碼

配置完以後,在命令行窗口中(Terminal)中輸入gradlew assembleRelease(windows)便可開始打包,在Mac系統中對應指令應該是./gradlew assembleRelease。固然,若是想要debug版本的包,將指令中assembleRelease改成assembleDebug便可。最後生成的包仍是在app/build/outputs/apk中,默認命名格式如app-wandoujia-release-unsigned.apk,在module的Build Variants中能夠選擇相應的渠道。
注:Android Studio3.0需在主app的build.gradle裏面的
defaultConfig {
targetSdkVersion:***
minSdkVersion :***
versionCode:***
versionName :***
//版本名後面添加一句話,意思就是flavor dimension 它的維度就是該版本號,這樣維度就是都是統一的了
flavorDimensions "versionCode"
}

2.九、lintOptions{}閉包:代碼掃描分析

Lint 是Android Studio 提供的 代碼掃描分析工具,它能夠幫助咱們發現代碼結構/質量問題,同時提供一些解決方案,並且這個過程不須要咱們手寫測試用例。

Lint 發現的每一個問題都有描述信息和等級(和測試發現 bug 很類似),咱們能夠很方便地定位問題,同時按照嚴重程度進行解決。

//程序在編譯的時候會檢查lint,有任何錯誤提示會中止build,咱們能夠關閉這個開關
    lintOptions {
        abortOnError false //即便報錯也不會中止打包
        checkReleaseBuilds false  //打包release版本的時候進行檢測
    }
複製代碼

三、dependencies{}閉包:

該閉包定義了項目的依賴關係,通常項目都有三種依賴方式:本地依賴、庫依賴和遠程依賴。本地依賴能夠對本地的jar包或目錄添加依賴關係,庫依賴能夠對項目中的庫模塊添加依賴關係,遠程依賴能夠對jcener庫上的開源項目添加依賴關係。從Android Studio3.0後compile引入庫不在使用,而是經過api和implementation,api徹底等同於之前的compile,用api引入的庫整個項目均可以使用,用implementation引入的庫只有對應的Module能使用,其餘Module不能使用,因爲以前的項目統一用compile依賴,致使的狀況就是模塊耦合性過高,不利於項目拆解,使用implementation以後雖然使用起來複雜了可是作到下降偶合興提升安全性。

dependencies {//項目的依賴關係
    implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依賴
    implementation 'com.android.support:appcompat-v7:27.1.1'//遠程依賴
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'//聲明測試用例庫
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

複製代碼
  • implementation fileTree(include: ['*.jar'], dir: 'libs'):implementation fileTree是一個本地依賴聲明,表示將libs目錄下全部.jar後綴的文件都添加到項目的構建路徑當中。
  • implementation 'com.android.support:appcompat-v7:27.1.1':implementation語句爲 遠程依賴聲明,'com.android.support:appcompat-v7:27.1.1'爲一個標準的遠程依賴庫格式,其中com.android.support爲域名部分,用於區分不一樣公司的庫;appcompat-v7爲組件名稱,用於區分同一個公司的不一樣庫;27.1.1爲版本號,用於區分同一個庫的不一樣版本。加上這句聲明後,Gradle在構建項目時會先檢查一下本地是否已經緩存過該庫,若沒有緩存則自動聯網下載,下載後自動添加到項目的構建路徑中去。
  • testImplementation和androidTestImplementation:表示聲明測試用例庫。

Module完整的build.gradle配置以下:

// 聲明是Android程序,
//com.android.application 表示這是一個應用程序模塊
//com.android.library 標識這是一個庫模塊
//而這區別:前者能夠直接運行,後着是依附別的應用程序運行
apply plugin: 'com.android.application'

android {
    signingConfigs {// 自動化打包配置
        release {// 線上環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
        debug {// 開發環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
    }
    compileSdkVersion 27//設置編譯時用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//項目的包名
        minSdkVersion 16//項目最低兼容的版本
        targetSdkVersion 27//項目的目標版本
        versionCode 1//版本號
        versionName "1.0"//版本名稱
        flavorDimensions "versionCode"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//代表要使用AndroidJUnitRunner進行單元測試
    }
    buildTypes {// 生產/測試環境配置
        release {// 生產環境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日誌
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則文件
            signingConfig signingConfigs.release//設置簽名信息
            pseudoLocalesEnabled false//是否在APK中生成僞語言環境,幫助國際化的東西,通常使用的很少
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減少zip體積,增長運行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
            versionNameSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
        }
        debug {// 測試環境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日誌
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則文件
            signingConfig signingConfigs.debug//設置簽名信息
            debuggable false//是否支持斷點調試
            jniDebuggable false//是否能夠調試NDK代碼
            renderscriptDebuggable false//是否開啓渲染腳本就是一些c寫的渲染方法
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減少zip體積,增長運行效率
            pseudoLocalesEnabled false//是否在APK中生成僞語言環境,幫助國際化的東西,通常使用的很少
            applicationIdSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
            versionNameSuffix 'test'//在applicationId 中添加了一個後綴,通常使用的很少
        }
    }

    sourceSets {//目錄指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib庫目錄
        }
    }

    packagingOptions{//打包時的相關配置
        //pickFirsts作用是 當有重複文件時 打包會報錯 這樣配置會使用第一個匹配的文件打包進入apk
        // 表示當apk中有重複的META-INF目錄下有重複的LICENSE文件時 只用第一個 這樣打包就不會報錯
        pickFirsts = ['META-INF/LICENSE']

        //merges何須 當出現重複文件時 合併重複的文件 而後打包入apk
        //這個是有默認值得 merges = [] 這樣會把默默認值去掉 因此咱們用下面這種方式 在默認值後添加
        merge 'META-INF/LICENSE'

        //這個是在同時使用butterknife、dagger2作的一個處理。同理,遇到相似的問題,只要根據gradle的提示,作相似處理便可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
    }

    productFlavors.all {
            //批量修改,相似一個循序遍歷
        flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
    }

    //程序在編譯的時候會檢查lint,有任何錯誤提示會中止build,咱們能夠關閉這個開關
    lintOptions {
        abortOnError false
        //即便報錯也不會中止打包
        checkReleaseBuilds false
        //打包release版本的時候進行檢測
    }

}

dependencies {
    //項目的依賴關係
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    //本地jar包依賴
    implementation 'com.android.support:appcompat-v7:27.1.1'
    //遠程依賴
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    //聲明測試用例庫
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
複製代碼
相關文章
相關標籤/搜索