什么是 Gradle ?
所謂構(gòu)建工具就是對你的項(xiàng)目進(jìn)行編譯嚷辅、運(yùn)行簿姨、簽名、打包簸搞、依賴管理等一系列功能的合集扁位,傳統(tǒng)的構(gòu)建工具有 Make、Ant趁俊、Maven域仇、Ivy等,而 Gradle 是新一代的自動(dòng)化構(gòu)建工具寺擂。
上面說了暇务,Gradle 是新一代的自動(dòng)化構(gòu)建工具泼掠,它是一個(gè)獨(dú)立的項(xiàng)目,跟 AS垦细、Android 無關(guān)择镇,官方網(wǎng)站:https://gradle.org/, 類似 Ant、Maven這類構(gòu)建工具都是基于 xml 來進(jìn)行描述的括改,很臃腫腻豌,而 Gradle 采用的是一種叫做 Groovy 的語言,語法跟 Java 語法很像叹谁,但是是一種動(dòng)態(tài)語言饲梭,而且在 Java 基礎(chǔ)上做了不少改進(jìn),用起來更加簡潔焰檩、靈活憔涉,而且 Gradle 完全兼容 Maven、Ivy析苫,這點(diǎn)基本上宣布了 Maven兜叨、Ivy 可以被拋棄了,Gradle 的推出主要以 Java 應(yīng)用為主衩侥,當(dāng)然目前還支持 Android国旷、C、C++茫死。
Gradle 與 Android Studio 的關(guān)系
上面也提到跪但,Gradle 跟 Android Studio 其實(shí)沒有關(guān)系,但是 Gradle 官方還是很看重 Android 開發(fā)的峦萎,Google 在推出 AS 的時(shí)候選中了 Gradle 作為構(gòu)建工具屡久,為了支持 Gradle 能在 AS 上使用,Google 做了個(gè) AS 的插件叫 Android Gradle Plugin 爱榔,所以我們能在 AS 上使用 Gradle 完全是因?yàn)檫@個(gè)插件的原因被环。在項(xiàng)目的根目錄有個(gè) build.gradle 文件,里面有這么一句代碼:
classpath ‘com.android.tools.build:gradle:2.3.3’
這個(gè)就是依賴 gradle 插件的代碼详幽,后面的版本號(hào)代表的是 android gradle plugin 的版本筛欢,而不是 Gradle 的版本,這個(gè)是 Google 定的唇聘,跟 Gradle 官方?jīng)]關(guān)系版姑。
Gradle基本組件
每一個(gè)build.gradle文件代表著一個(gè)Project。Tasks在build.gradle中定義迟郎。當(dāng)初始化構(gòu)建進(jìn)程時(shí)漠酿,gradle會(huì)基于build文件,集合所有的Project和Tasks,一個(gè)Tasks包含了一系列動(dòng)作谎亩,然后它們將會(huì)按照順序執(zhí)行炒嘲,一個(gè)動(dòng)作就是一段被執(zhí)行的代碼宇姚,很像Java中的方法。
Project
每一個(gè)待編譯的工程(可以是一個(gè)jar包夫凸,一個(gè)web應(yīng)用浑劳,或者一個(gè)android app等)都稱為一個(gè)Project。
Task
每一個(gè)Project在構(gòu)建的時(shí)候都包含一系列的Task夭拌。一個(gè)Task其實(shí)就是構(gòu)建過程中一個(gè)原子性的操作魔熏。比如一個(gè)Android APK的編譯可能包含:Java源碼編譯Task、資源編譯Task鸽扁、JNI編譯Task蒜绽、lint檢查Task、打包生成APK的Task桶现、簽名Task等躲雅。
Plugin
Gradle是一個(gè)框架,作為框架骡和,它負(fù)責(zé)定義流程和規(guī)則相赁。而具體的編譯工作則是通過插件的方式來完成的。比如編譯Java有Java插件慰于,編譯Groovy有Groovy插件钮科,編譯Android APP有Android APP插件,編譯Android Library有Android Library插件婆赠。
簡單來說绵脯,插件就是一系列任務(wù)的集合,主要作用是把一些重復(fù)利用的邏輯打包休里,這樣就可以在不同的項(xiàng)目中可以重復(fù)的使用桨嫁。
要使用插件,可以通過引入依賴的方式添加份帐。
As如何依賴Gradle讓Gradle作為自身的構(gòu)建工具呢?
Google開發(fā)了一個(gè)Gradle插件楣导,讓As項(xiàng)目依賴這個(gè)插件废境,就相當(dāng)于讓Gradle作為自身的的構(gòu)建工具。
現(xiàn)在比如我們新建一個(gè)As項(xiàng)目筒繁,打開項(xiàng)目的根目錄的gradle.build文件噩凹。有如下代碼:
buildscript {
? ? ?repositories {
? ? ? ? ? ? ? ?jcenter() ? ?//表示編譯過程中依賴的倉庫
? ? ?}
? ? ?dependencies {
? ? ? ? ? ? ? classpath 'com.android.tools.build:gradle:2.2.0' ? ? //依賴android開發(fā)使用的gradle插件
? ? ? }
}
而要引入Android APP插件,就需要在build.gradle引用Android APP插件:
//申明使用插件毡咏,表明要編譯的內(nèi)容和產(chǎn)物
apply plugin: 'com.android.application'
//配置插件屬性
android {
? ? ? ? compileSdkVersion 24
? ? ? ? buildToolsVersion "24.0.1"
? ? ? ? defaultConfig {
? ? ? ? ? ? ? ? applicationId "zhj.gradledemo"
? ? ? ? ? ? ? ? minSdkVersion 15
? ? ? ? ? ? ? ? targetSdkVersion 24
? ? ? ? ? ? ? ? versionCode 1
? ? ? ? ? ? ? ? versionName "1.0"
? ? ? ? ? ? ? ? testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
? ? ? ? ?}
? ? ? ? ?buildTypes {
? ? ? ? ? ? ? ?release {
? ? ? ? ? ? ? ? ? ? ? minifyEnabled false
? ? ? ? ? ? ? ? ? ? ? proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
? ? ? ? ? ? ? ?}
? ? ? ? ? }
}
Android其實(shí)就是寫了兩個(gè)插件:com.android.application 和 com.android.library?
應(yīng)用這兩個(gè)插件就可以實(shí)現(xiàn)Android APP和Android Library的構(gòu)建驮宴。
.gradle文件夾
.gradle文件夾 是gradle 運(yùn)行以后生成的緩存文件夾。
Project中的build.gradle文件
project下的build.gradle是基于整個(gè)project的配置呕缭,主要配置gradle 版本及全局依賴倉庫堵泽、庫或者其他全部參數(shù)修己。
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
? ? ? ? repositories {
? ? ? ? ? ? ? ? //這里依賴的jcenter倉庫是gradle腳本自身需要的資源
? ? ? ? ? ? ? ? jcenter()
? ? ? ? }
? ? ? ? dependencies {
? ? ? ? ? ? ? ? classpath 'com.android.tools.build:gradle:2.2.0'
? ? ? ? ? ? ? ? ?// NOTE: Do not place your application dependencies here; they belong
? ? ? ? ? ? ? ? ?// in the individual module build.gradle files
? ? ? ? ?}
}
allprojects {
? ? ? ? ?repositories {
? ? ? ? ? ? ? ? ?//這里依賴的jcenter倉庫是項(xiàng)目所有模塊需要的資源
? ? ? ? ? ? ? ? ?jcenter()
? ? ? ? ?}
}
task clean(type: Delete) {
? ? ? ?delete rootProject.buildDir
}
module中build.gradle文件
//申明使用插件,表明要編譯的內(nèi)容和產(chǎn)物
apply plugin: 'com.android.application'
android {
? ? ? ?? compileSdkVersion 24
? ? ? ?? buildToolsVersion "24.0.1"
? ? ? ?? //默認(rèn)配置迎罗,會(huì)同時(shí)應(yīng)用到debug和release版本上
? ? ? ?? defaultConfig {
? ? ? ?? ? ? ? ?? applicationId "zhj.gradledemo"
? ? ? ?? ? ? ? ?? minSdkVersion 15
? ? ? ?? ? ? ? ?? targetSdkVersion 24
? ? ? ?? ? ? ? ?? versionCode 1
? ? ? ?? ? ? ? ?? versionName "1.0"
? ? ? ?? ? ? ? ?? testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
? ? ? ?? }
? ? ? ?? buildTypes {
? ? ? ?? ? ? ? ?? release {
? ? ? ?? ? ? ? ?? ? ? ? ?? minifyEnabled true? //是否混淆
? ? ? ?? ? ? ? ?? ? ? ? ?? proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //混淆文件的位置
? ? ? ?? ? ? ? ?? }
? ? ? ?? ? ? ? ?? debug {
? ? ? ?? ? ? ? ?? ? ? ? ?? minifyEnabled false
? ? ? ?? ? ? ? ?? }
? ? ? ?? }
? ? ? ?? // 多渠道
? ? ? ?? productFlavors {
? ? ? ?? //可以設(shè)置不同渠道渠道號(hào)睬愤,應(yīng)用名稱
? ? ? ?? ? ? ? ?? pro {
? ? ? ?? ? ? ? ?? }
? ? ? ?? ? ? ? ?? fre {
? ? ? ?? ? ? ? ?? }
? ? ? ?? }
}
//依賴第三方庫
dependencies {
? ? ? ?? //編譯libs目錄下所以jar包
? ? ? ?? compile fileTree(include: ['*.jar'], dir: 'libs')? //導(dǎo)入所有的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.0'
? ? ? ?? compile 'com.android.support:design:24.2.0'
? ? ? ?? testCompile 'junit:junit:4.12'
? ? ? ?? proCompile 'com.android.support:recyclerview-v7:24.2.0'
}
Project中setting.gradle
這個(gè)文件是全局的項(xiàng)目配置文件,里面主要聲明Project中所包括的所有module
//一個(gè)Project中所包括的所有module
include ':Gotobus', ':android-support-v7-appcompat'
include ':google-play-services_lib'
include ':TakeTours'
include ':Common'
include ':CompanyCommon'
Project中g(shù)radle.properties
//編譯版本信息
APPLICATION_ID = com.jin.myAPP
COMPILE_SDK_VERSION = 23
BUILD_TOOLS_VERSION = 23.0.1
MIN_SDK_VERSION = 15
TARGET_SDK_VERSION = 1
VERSION_CODE = 1
VERSION_NAME = 1.0.0.0
//keystore信息
STORE_FILE = ../app/mykey.keystore
STORE_PASSWORD = your password
KEY_ALIAS = your alias
KEY_PASSWORD = your password
配置應(yīng)用的簽名信息
在android.signingConfigs{}下定義一個(gè)或者多個(gè)簽名信息纹安,然后在buildTypes{}配置使用即可尤辱。比如這里:
android {
? ? ? ? signingConfigs {
? ? ? ?? ? ? ? ?? release {
? ? ? ?? ? ? ? ?? ? ? ? ?? storeFile file("release.keystore")
? ? ? ?? ? ? ? ?? ? ? ? ?? keyAlias "release"
? ? ? ?? ? ? ? ?? ? ? ? ?? keyPassword "123456"
? ? ? ?? ? ? ? ?? ? ? ? ?? storePassword "123456"
? ? ? ?? ? ? ? ?? }
? ? ? ?? ? ? ? ?? debug {
? ? ? ?? ? ? ? ?? ? ? ? ?? ...
? ? ? ?? ? ? ? ?? }
? ? ? ?? }
? ? ? ?? buildTypes {
? ? ? ? ? ? ? ?? release {
? ? ? ? ? ? ? ? ? ? ? ? ?? signingConfig signingConfigs.release
? ? ? ?? ? ? ? ?? }
? ? ? ?? ? ? ? ?? debug {
? ? ? ? ? ? ? ? ? ? ? ? ?? signingConfig signingConfigs.debug
? ? ? ?? ? ? ? ?? }
? ? ? ?? ?}
}
storeFile是簽名證書文件,keyAlias是別名厢岂,keyPassword是key的密碼光督,storePassword是證書的密碼。配置好相關(guān)信息即可在buildTypes配置使用塔粒。
一般重要的信息结借,例如簽名信息,可以直接將信息寫到gradle.properties窗怒,然后在然后在build.gradle中引用即可映跟。
buildTypes是指建構(gòu)的類型,一般只用兩種默認(rèn)類型 debug 和 release 扬虚,顧名思義 debug 用來配置開發(fā)過程中的一些內(nèi)容努隙;release 用來配置正式發(fā)布版本的內(nèi)容。有時(shí)我們需要發(fā)布介于debug與release之間的preview 版本辜昵。
Build Variant 差異管理
比如app生成不同版本(免費(fèi)荸镊,收費(fèi)),適配特殊機(jī)型堪置,多渠道等需要發(fā)多個(gè)包躬存,最終能編譯出的apk的數(shù)量是由Product Flavor(產(chǎn)品種類)與Build Type(構(gòu)建類型)決定的,
公式:Build Variant = Build Type x Product Flavor
BuildType(構(gòu)建類型)
默認(rèn)有debug和release兩種舀锨,標(biāo)示編譯的類型岭洲,通常在混淆代碼、可調(diào)式坎匿、資源壓縮上做一些區(qū)分盾剩。
Product Flavor(產(chǎn)品種類)
為了滿足“同一個(gè)project,根據(jù)一個(gè)很小的區(qū)分替蔬,來打不同的包”這個(gè)需求告私。實(shí)現(xiàn)多渠道打包。注意:這里的Flavor名如果是數(shù)字開頭承桥,必須用引號(hào)引起來驻粟。
調(diào)整module的目錄結(jié)構(gòu)sourceSets
默認(rèn)情況下,java文件和resource文件分別在src/main/java和src/main/res目錄下凶异,在build.gradle文件的andorid{}里面添加下面的代碼蜀撑,便可以將java文件和resource文件放到src/java和src/resources目錄下挤巡。
sourceSets {
? ? ? ? ?main {
? ? ? ? ? ? ? ? ? manifest.srcFile 'AndroidManifest.xml'
? ? ? ? ? ? ? ? ? //設(shè)置java文件的位置
? ? ? ? ? ? ? ? ? java.srcDirs = ['src']
? ? ? ? ? ? ? ? ? resources.srcDirs = ['src']
? ? ? ? ? ? ? ? ? aidl.srcDirs = ['src']
? ? ? ? ? ? ? ? ? renderscript.srcDirs = ['src']
? ? ? ? ? ? ? ? ? res.srcDirs = ['res']
? ? ? ? ? ? ? ? ? assets.srcDirs = ['assets']
? ? ? ? }
}
全局變量定義及引用
可以在頂層build.gradle腳本中定義一些全局變量,提供給子腳本引用
ext {
? ? ? ? // global variables definition
? ? ? ? compileSdkVersion = 'Google Inc.:Google APIs:23'
? ? ? ? buildToolsVersion = "23.0.3"
? ? ? ? minSdkVersion = 14
? ? ? ? targetSdkVersion = 23
}
子腳本引用
android {
? ? ? ? compileSdkVersion rootProject.ext.compileSdkVersion
? ? ? ? buildToolsVersion rootProject.ext.buildToolsVersion
? ? ? ? defaultConfig {
? ? ? ? ? ? ? ? minSdkVersion rootProject.ext.minSdkVersion
? ? ? ? ? ? ? ? targetSdkVersion rootProject.ext.targetSdkVersion
? ? ? ? ?}
}