Gradle是一個自動化構建工具,採用Groovy的Domain Specific Language(領域特定語言)來描述和控制構建邏輯。具備語法簡潔、可讀性強、配置靈活等特色。基於Intellij IDEA社區版本開發的Android Studio天生支持Gradle構建程序。Groovy是一種基於JVM的敏捷開發語言,結合了Phthon、Ruby和Smalltalk的許多強大特性。同時,Groovy代碼既可以與java代碼很好地結合,也可以用於擴展示有的代碼。
Gradle有以下特色:html
在Android Studio下建立一個Android項目,並切換到Project視圖下,能夠看到下圖的項目結構。
紅框標記就是項目中Gradle相關的配置文件,下面咱們從app模塊下的build.gradle開始對各個配置文件進行分析。java
app這個Module下的gradle配置文件,算是整個項目最主要的gradle配置文件,主要配置應用程序屬性、配置應用程序簽名、配置應用程序特性(渠道)、配置應用程序構建類型和配置應用程序依賴,下圖是默認生成的文件內容:
android
apply plugin:
‘com.android.application’//這表示此module是一個可運行的應用程序,能夠直接run的
apply plugin: ‘com.android.library’//這表示此module是一個安卓依賴庫的工程,不可直接run
apply plugin: ‘java’//這表示此module是一個java項目,在此module中只能使用java的api
其默認有compileSdkVersion、buildToolsVersion、defaultConfig閉包和buildTypes閉包。
compileSdkVersion和buildToolsVersion是兩個關於版本描述的參數api
compileSdkVersion 25//指定編譯版本,開發採用的sdk版本
buildToolsVersion 「25.0.2」//編譯時採用的構建工具的版本
defaultConfig閉包參數說明android-studio
applicationId 「com.jointem.variantpackaging」//應用的id,這裏決定應用的惟一標識
minSdkVersion 17//決定此應用可運行的安卓系統最低版本
targetSdkVersion 25//決定此應用可運行的安卓系統最高版本
versionCode 1//應用版本號,更新須要,新包的值要大於老包的方可更新
versionName ‘1.0’//應用版本名,一般用於顯示
testInstrumentationRunner」andrid.support.test.runner.AndroidJUnitRunner」//Android單元測試test runner
buildTypes閉包參數說明
關於構建類型buildType,默認有release和debug兩種,默認只顯示release方式,通常是正式發佈的包。markdown
minifyEnabled false//混淆開關
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’// 指定混淆文件及混淆文件規則配置文件的位置
compile fileTree(include: [‘*.jar’], dir: ‘libs’)//編譯文件樹(編譯依賴libs目錄下全部jar)
androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2’, {
exclude group: ‘com.android.support’, module: ‘support-annotations’
})
compile ‘com.android.support:appcompat-v7:24.2.1’//是從repository(默認是jCenter())裏下載一個依賴包進行編譯並打包
compile ‘com.android.support.constraint:constraint-layout:1.0.0-beta5’
testCompile ‘junit:junit:4.12’// 僅僅是針對單元測試代碼的編譯編譯以及最終打包測試apk時有效,而對正常的debug或者release apk包不起做用
compile project(‘:andr-library’)//是將另外一個module進行編譯並打包
其實,app下的腳本對應的是項目的Project Structure對話框中的設置,從左到右依次是屬性、簽名、渠道特性、構建類型和依賴,快捷鍵Ctrl+Shift+Alt+S(Windows/Linux),以下。
網絡
除了app Module,每個Module也都有一個gradle配置文件,語法都同樣,區別在於開頭聲明的是apply plugin: ‘com.android.library’,代表該Module是以依賴模塊的形式存在。閉包
全部的全局配置文件都會放置在項目的根目錄下,包括忽略文件、本地配置文件、gradlew的批處理文件以及項目gradle相關的配置文件。app
#Thu Mar 09 16:27:37 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
此配置文件中主要聲明瞭gradle的目錄與下載路徑以及當前項目使用的gradle版本,這些默認的路徑咱們通常不會更改的,這個文件裏指明的gradle版本不對也是不少導包不成功的緣由之一。框架
整個項目的gradle基礎配置文件,用來配置項目的構建任務,內容以下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.// 項目構建文件,能夠在各子項目/模塊添加經常使用的配置選項。
buildscript {
//Android插件從這個倉庫下載
repositories {
jcenter()//依賴倉庫源的名稱,兼容maven的遠程中央倉庫
}
//項目依賴
dependencies {
//android gradle插件
classpath 'com.android.tools.build:gradle:2.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
//此處配置Project中默認的倉庫源,包括每一個module的依賴,無需每一個module單獨配置
repositories {
jcenter()
}
} //打包前執行clean任務 //任務類型是Delete //clean任務就是刪除項目根目錄下的build目錄中的文件
task clean(type: Delete) {
delete rootProject.buildDir
}
gradle.properties是Gradle的配置文件,build.gradle經過讀取這個文件配置的參數來進行相應構建,可在此配置文件中配置一些全局參數(全局代理)。默認文件內容以下:
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# 配置守護進程的jvm參數
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
#配置完成後,Gradle將在並行模式下運行(並行編譯)
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
#http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
默認文件內容include ‘:app’。是項目的全局配置文件,主要聲明一些須要加入構建的模塊。在Android studio中一般都是默認自動在此文件中添加依賴的module。
按快捷鍵Ctrl+Shift+Alt+S(Windows/Linux),打開Project Structure彈窗。
在Dependencies下有個scope,這裏能夠選擇依賴的方式,可選項有Compile、Provided、APK、Test compile、Debug compile和Release compile,下面分別對這些可選項進行簡單說明。
compile fileTree(dir: 'libs', include: '*.jar')
,即,將libs目錄下全部jar文件進行編譯並打包。在開發過程當中常常遇到多個環境切換的問題,好比,正在鏈接測試環境進行調試,此時又想看生產環境的數據顯示,一般的處理方式是卸掉測試環境的而後運行一個生產環境的包。咱們都知道,build一個大項目,直到安裝到手機上,整個過程是很耗時的。若是同一臺手機上能夠同時安裝同一個應用的多個不一樣環境的apk,那麼,當想看其它環境的數據時,就不須要從新卸載再安裝了(同理,同一應用,須要不一樣版本的安裝包[免費版/收費版]時,也能夠這樣處理,而無需爲不一樣版本建立不一樣的分支)。
在建立完一個項目後,咱們在app這個module下的build.gradle中的android節點下defaultConfig節點中,能夠看到一個applicationId屬性,默認的 applicationId 和 AndroidManifest.xml 中的 package 屬性是相同的。applicationId 和 packageName 它們各自表明什麼?爲什麼會是相同的呢?其實,package 表明了 java 代碼中的包名,在應用中的資源,就是經過package標識的(好比R文件,包名.R);applicationId 則表明了應用中的惟一標識,和應用簽名一塊兒用來區別於其餘應用。
在手機上,系統一樣是經過applicationId和簽名來標識一個app的。因此,咱們只要在打包apk時,使得應用之間的applicationId和簽名各不相同,就可以實現同一個應用的不一樣變體同時安裝在同一臺手機上了。同時,爲了更好的區分給個變體應用,咱們還能夠經過對佔位符的使用,使用gradle配置不一樣的資源文件、不一樣的應用名稱與圖標、不一樣的java文件等有區別的屬性,打出不一樣的變體包。
選擇app module,選擇Signing選項卡,首先配置好了這兩個變體版本的簽名文件,文件名可任意取(見名知意)。
簽名屬性字段描述:
切換到Flavors選項卡,配置變體包的相關屬性,因爲下一步建立資源文件夾時,須要與這裏的文件名對應,因此此處的取名儘可能簡約。這裏我建立兩個命名dev和rea的Flavor,全部的Flavor都會複寫defaultConfig中的屬性,因此能夠看到我並無填寫其中的一些屬性。在這裏很是關鍵的一點,是對不一樣的變體設置不一樣的applicationId,並選擇對應的Signing Config。
在修改完變體的配置文件後,咱們還須要再項目的src文件夾下,新建以咱們的Flavor名稱命名的文件夾,並在這些文件夾下新建如main中相同的目錄結構。
咱們正常編寫項目都是寫在main這個sourceSet下的,可是若是咱們的項目的變體有不一樣的資源文件、Java文件時,咱們就須要使用不一樣的sourceSet來區別開。
須要注意的是,Flavor下的資源文件會與main中的合併,若是存在重複,則Flavor中優先級高於main中。咱們能夠將不一樣變體中共用的資源存放在main中,只將不一樣的內容存放在flavor的sourceSet中。
若是不一樣變體有內容不一樣的Java文件則要注意,須要將這個Java文件放置到每一個flavor 的sourceSet文件夾下,main中不能夠有這個Java文件,若是main中也存在此文件,編譯時會提示文件重複。好比說有兩個變體,有着不一樣的TargetActivity.java,那麼main中就不能有這個文件了,須要把這個Java文件放到各個flavor的sourceSet下,同時這個Java文件在sourceSet中要按照main中的包結構保存。
經過以前的操做,已經能夠有效區分變體包的applicationId、Signing Config和java文件,那麼應用logo和name又該如何處理呢,這裏有兩種方法。
1)配置不一樣的資源:咱們可使用相似於處理java文件的方法,在不一樣的sourceSet中配置string.xml中app_name屬性,在mipmap文件夾中放置對應的ic_app.png圖標資源。不過當咱們須要更換啓動圖和應用名而變體包又比較多的狀況下,這種方法會比較麻煩,由於咱們要到每個sourceSet資源文件下去對應的修改,若是使用佔位符的方式,那麼會變得簡單一些。
2)使用佔位符的方式:在AndroidManifest文件中使用佔位符而後在flavor中直接配置,在flavor中使用的屬性是manifestPlaceholderss(manifestPlaceholders =[NAME1:VALUE1]),而圖標資源和應用名稱咱們均可以直接放置到main中。
結果以下圖:
經過以前的操做,已經成功配置了多個變體,那麼問題來了,這麼多個變體,咱們在debug的時候,咱們怎麼選擇要debug的變體呢?這裏有兩種方式進行切換。
首次運行命令行,沒有gradle的要下載的哦,下載須要的時間根據網絡情況而定。
- ./gradlew -v //查看gradle版本
- ./gradlew assembleDebug //編譯並打出Debug版本的包
- ./gradlew assembleRelease //編譯並打出Release版本的包
- ./gradlew build //執行檢查並編譯打包,打出全部Release和Debug的包
- ./gradlew clean //刪除build目錄,會把app下面的build目錄刪掉
- ./gradlew installDebug //編譯打包並安裝Debug版本的包
- ./gradlew uninstallDebug //卸載Debug版本的包
- ./gradlew -info //使用-info查看任務詳情
咱們直接利用./gradlew build打出全部的變體包,在Terminal終端下鍵入./gradlew build命令,須要等待大概20秒鐘左右,當看到終端打印出BUILD SUCCESSFUL,說明打包任務執行完成,打開指定的apk生成目錄(默認app/build/outputs/apk),就能夠看到已經打出的apk。
將兩個release包都安裝到同一臺手機,能夠發現能同時存在,而且都能正常打開運行。
若是項目中存在使用Library Module,而且Library Module中manifest下的application也存在與app Module下的application相同的屬性標籤,那麼會報manifest.xml合併錯誤的提示,以下。
注:本篇博客純屬我的筆記,若是錯誤之處,還望幫忙指正,謝謝!