- 閱讀本文需要10min+
關(guān)鍵字
Gradle、groovy
目錄
- 前言
- 簡(jiǎn)介
- groovy
- 簡(jiǎn)介
- 數(shù)據(jù)語(yǔ)法
- 數(shù)據(jù)類型
- gradle
- 簡(jiǎn)介
- 依賴管理
- 幾個(gè)常用Task
- 新版本gradle屬性介紹( android plugin 3.0.0搭配Gradle 3.4版本以上)
- 最佳實(shí)踐
- 實(shí)踐一
- 實(shí)踐二
- 參考
前言
Gradle的知識(shí)體系非常龐大,市面上有專門(mén)講解的書(shū)籍,如果想全面了解可以購(gòu)買(mǎi)書(shū)籍或者查看網(wǎng)上的系列教程。本文只帶你入門(mén)以及熟悉在Android下常見(jiàn)的使用場(chǎng)景。
簡(jiǎn)介
gradle還是glide?作為一個(gè)Android開(kāi)發(fā)者,有時(shí)候會(huì)把兩者給拼寫(xiě)錯(cuò)誤,前者也就是本文的主角,是一個(gè)自動(dòng)化構(gòu)建(build)的工具,說(shuō)到構(gòu)建,有的同學(xué)可能不太理解,初略的理解就是根據(jù)輸入的信息執(zhí)行一些操作,然后得到目標(biāo)產(chǎn)物的過(guò)程稱為構(gòu)建。構(gòu)建不同于編譯工具,它用于組織編譯,單元測(cè)試,發(fā)布等操作。這里提到構(gòu)建,就順便提一下構(gòu)建工具的發(fā)展史
- Makefile
這是什么鬼,我也不熟,不過(guò)據(jù)說(shuō)是最元老的構(gòu)建工具,至今仍然是Linux上C/C++開(kāi)發(fā)最流行的構(gòu)建工具,上了G界別的Android系統(tǒng)的開(kāi)源項(xiàng)目就是由Makefile構(gòu)建 - Ant
Java出世,是為跨平臺(tái)而生,而Makefile成了一個(gè)大大的絆腳石,Java開(kāi)發(fā)人員急切的需要一個(gè)跨平臺(tái)的構(gòu)建工具,最好能在JVM上運(yùn)行,于是Ant誕生了,Ant使用的xml文件格式 - Maven
Ant出現(xiàn),為很多Java開(kāi)發(fā)者帶來(lái)了福音,不過(guò)伴隨著軟件行業(yè)的日益發(fā)展,規(guī)模變大,大家發(fā)現(xiàn)Ant不夠用,于是Maven出世,Maven他使用XML文件格式(pom.xml) - Gradle
2004年,Maven發(fā)布后,非常受Java開(kāi)發(fā)人員愛(ài)戴,然而,軟件史上,再偉大的項(xiàng)目都有他喪失光芒的一天,于是gradle出世了,在他問(wèn)世之后,Google迅速把Android的編譯環(huán)境遷移到gradle,當(dāng)你搜索gradle時(shí),你應(yīng)該會(huì)有這樣的感覺(jué),為何人們都如此愛(ài)好這個(gè)工具,其中很大一部分原因是gradle使用了基于Groovy的DSL語(yǔ)言作為構(gòu)建腳本語(yǔ)言的而不是以往的XML。
PS: 有關(guān)構(gòu)建工具的發(fā)展的詳細(xì)歷史,可以參考[這篇文章](http://blog.csdn.net/yanquan345/
article/details/46710869)
groovy
簡(jiǎn)介
Groovy是一種動(dòng)態(tài)語(yǔ)言,和Java一樣,運(yùn)行在Java虛擬機(jī)中,簡(jiǎn)單粗暴的理解,可以認(rèn)為Groovy擴(kuò)展了Java語(yǔ)言,除了語(yǔ)言和Java相通外,Groovy有時(shí)候又像一種腳本語(yǔ)言。當(dāng)我執(zhí)行 Groovy 腳本時(shí),Groovy 會(huì)先將其編譯成 Java 類字節(jié)碼,然后通過(guò) Jvm 來(lái)執(zhí)行這個(gè) Java 類,實(shí)際上,由于 Groovy Code 在真正執(zhí)行的時(shí)候已經(jīng)變成了 Java 字節(jié)碼,所以 JVM 根本不知道自己運(yùn)行的是 Groovy 代碼。
使用Groovy 還可以開(kāi)發(fā)Android應(yīng)用,可以參考[這篇文章](http://www.itdecent.cn/p/
399ae2d0f313)
數(shù)據(jù)語(yǔ)法
既然Groovy是一種語(yǔ)言,它必然有他的語(yǔ)言編寫(xiě)規(guī)則,下面只粗略的介紹,更多細(xì)節(jié)可以查看官方文檔
- Groovy 注釋標(biāo)記和 Java 一樣,支持//或者/**/
- Groovy 語(yǔ)句可以不用分號(hào)結(jié)尾。
- Groovy 中支持動(dòng)態(tài)類型,即定義變量的時(shí)候可以不指定其類型。Groovy 中,變量定義可以使用關(guān)鍵字 def。注意,雖然 def 不是必須的,但是為了代碼清晰,建議還是使用 def 關(guān)鍵字
def variable1 = 1 //可以不使用分號(hào)結(jié)尾
def varable2 = "I am a person"
def int x = 1 //變量定義時(shí),也可以直接指定類型
- 函數(shù)定義時(shí),參數(shù)的類型也可以不指定。
String testFunction(arg1,arg2){//無(wú)需指定參數(shù)類型
...
}
數(shù)據(jù)類型
- 一個(gè)是 Java 中的基本數(shù)據(jù)類型。
- 另外一個(gè)是 Groovy 中的容器類。
- 最后一個(gè)非常重要的是閉包。
這一塊的知識(shí)點(diǎn)詳細(xì)可以查看[這個(gè)地址](http://wiki.jikexueyuan.com/project/deep-android- gradle/three-three.html),如果你想詳細(xì)了解Groovy這門(mén)語(yǔ)言,可以查看IBM的中文教程,更多細(xì)節(jié)可以查看官方文檔
gradle
簡(jiǎn)介
Gradle是一個(gè)框架,它定義了一套自己的規(guī)則。Gradle 中,每一個(gè)待編譯的工程都叫一個(gè) Project。我們點(diǎn)擊build.gradle會(huì)跳轉(zhuǎn)到gradle源碼Project.java類中,每一個(gè) Project 在構(gòu)建的時(shí)候都包含一系列的 Task。比如一個(gè) Android APK 的編譯可能包含:Java 源碼編譯 Task、資源編譯 Task、JNI 編譯 Task、lint 檢查 Task、打包生成 APK 的 Task、簽名 Task 等(在后面我們會(huì)專門(mén)介紹幾個(gè)常用Task)。
Android Studio幾個(gè)有關(guān)gradle的配置文件,如下圖

依賴管理
首先我們看下面一段gradle代碼
apply plugin: 'com.android.application'
repositories {
jcenter()
}
dependencies {
compile 'com.android.support:appcompat-v7:26.+‘
testCompile 'junit:junit:4.12'
}
這段腳本是什么意思呢?首先com.android.support:appcompat-v7:26.+(倉(cāng)庫(kù)中26版本下的最新版,不過(guò)官方不建議這么寫(xiě))這貨是編譯期必須依賴,并且它相關(guān)的依賴也會(huì)一起加載進(jìn)來(lái)(v4包),該腳本同時(shí)還申明項(xiàng)目測(cè)試階段需要4.12版本的junit。同時(shí)告訴gradle可以去jcenter倉(cāng)庫(kù)去加載這些依賴,下面將較詳細(xì)的描述。
依賴配置
- 按依賴的作用分為以下幾部分
- compile
編譯范圍依賴在所有的classpath范圍可用,同時(shí)它們也會(huì)被打包到apk中 - apk
apk的意思是apk中存在,但是不會(huì)加入編譯中(用的比較少) - provided
提供編譯支持,但是不會(huì)寫(xiě)入apk - runtime
runtime依賴在運(yùn)行和測(cè)試系統(tǒng)的時(shí)候需要,編譯的時(shí)候不需要 - testCompile&androidTestCompile
測(cè)試編譯需要附加的依賴
- compile
PS: 在gradle3.4版本,以上配置關(guān)鍵字被調(diào)整優(yōu)化了,下面會(huì)講解到。
測(cè)試運(yùn)行期需要的依賴
- 按依賴的加入方式分為兩種
(1) 遠(yuǎn)程依賴
遠(yuǎn)程依賴指的是library被放置到遠(yuǎn)程(可以是自己的maven庫(kù)或者是maven中心庫(kù)或jcenter),需要的時(shí)候在maven方法加入url地址
repositories {
maven {
url "http://repo.acmecorp.com/maven2"
}
}
(2) 本地依賴
- 文件依賴
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
默認(rèn)新建Android項(xiàng)目會(huì)自動(dòng)生成這端代碼,這段代碼的意思是把libs文件夾下的所有jar文件添加到編譯路徑以及最后的apk文件(如果你想添加單個(gè)文件可以compile files('libs/okhttp.jar'))
- arr依賴
首先得先把a(bǔ)rr文件拷貝到自己創(chuàng)建的一個(gè)文件夾(比如arrs),然后把a(bǔ)rr文件拷貝到該文件夾里,然后添加該文件夾作為依賴庫(kù)
repositories {
flatDir {
dirs 'aars'
}
}
最后把該文件夾下的arr作為依賴
dependencies {
compile(name:'libraryname', ext:'aar')
}
這個(gè)會(huì)告訴gradle,在aars文件夾下,添加一個(gè)叫做libraryname的文件,且其后綴是aar的作為依賴。
- 工程依賴
如果把其他工程作為模塊,需要在setting.gradle文件添加
include ':app', ':library'
然后在module使用該依賴
dependencies {
compile project(':library')
}
- narive包(so包)
使用c/c++編寫(xiě)的library會(huì)叫做so包,Android插件默認(rèn)支持native包,把.so文件放入對(duì)應(yīng)的文件夾中:
app
├── AndroidManifest.xml
└── jniLibs
├── armeabi
│ └── nativelib.so
├── armeabi-v7a
│ └── nativelib.so
├── mips
│ └── nativelib.so
└── x86
└── nativelib.so
幾個(gè)常用Task
在Android Studio 的Terminal輸入"./gradlew tasks --all",數(shù)據(jù)一大串task,如下(圖片太大,我把其分為三部分)



這里列出里Project ArchitectureSample支持的Task(Task 也可以自定義),這里簡(jiǎn)介一下我常用的一些Task,更多命令可以查看gradle官方文檔
./gradlew -v //查看構(gòu)建版本
./gradlew assembleDebug //編譯并打Debug包
./gradlew assembleRelease // 編譯并打Release的包
./gradlew installRelease // Release模式打包并安裝
./gradlew uninstallRelease //卸載Release模式包
./gradlew -q app:dependencies //查看app module下的依賴
./gradlew install[productFlavorsName] app:assembleDebug//結(jié)合productFlavors多渠道打包
注意:在window下可以直接運(yùn)行 gradlew 如果是Linux 或者 mac 命令為 gradle gradlew 這里都簡(jiǎn)寫(xiě)成 ./gradle
新版本gradle屬性介紹( android plugin 3.0.0搭配Gradle 3.4版本以上)
- Implementation vs compile
升級(jí)到新版本的gradle,發(fā)現(xiàn)Android Studio 新建工程發(fā)現(xiàn)默認(rèn)添加的依賴改成了Implementation,而不是之前的compile,同樣替換的有 api 替換compile compileOnly 替換provided ,runtimeOnly替換apk,Implementation較compile有什么改進(jìn)呢,簡(jiǎn)單一句話就是加快了編譯速度,稍微復(fù)雜的一句話就是Implementation較compile改動(dòng)底層library不需要重新編譯整個(gè)Project,更細(xì)節(jié)可以看這篇文章,更多新特性可以查看相應(yīng)官方文檔
ps:如果沒(méi)有升級(jí)的建議盡快升級(jí),為了更好的體驗(yàn),下面的截圖取自官方文檔是不同版本編譯速度的比較gradle不同版本速度比較
最佳實(shí)踐
實(shí)踐一
在module的build.gradle
android {
compileSdkVersion project.COMPILE_SDK as int
buildToolsVersion project.BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion project.MIN_SDK as int
targetSdkVersion project.TARGET_SDK as int
.....
}
......
}
dependencies {
compile "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}"
compile "com.squareup.retrofit2:retrofit:${retrofit}"
compile "com.squareup.retrofit2:converter-gson:${retrofit}"
compile "com.squareup.retrofit2:converter-scalars:${retrofit}"
compile "com.squareup.okhttp3:okhttp:${OKHTTP}"
compile "com.squareup.okhttp3:logging-interceptor:${OKHTTP}"
......
}
在gradle.properties直接定義
COMPILE_SDK=25
MIN_SDK=16
TARGET_SDK=25
BUILD_TOOLS_VERSION=25.0.3
SUPPORT_LIBRARY=25.0.1
OKHTTP=3.6.0
retrofit = 2.2.0
實(shí)踐二
在project根目錄新建versions.gradle
ext {
android = [
compileSdkVersion : 25,
buildToolsVersion : "25.0.3",
minSdkVersion : 15,
targetSdkVersion : 25,
versionCode : 130,
versionName : "2.1.5"
]
version = [
androidSupportSdkVersion: "25.4.0",
retrofitSdkVersion : "2.3.0",
glideSdkVersion : "4.0.0",
butterknifeSdkVersion : "8.7.0",
rxlifecycleSdkVersion : "1.0",
rxlifecycle2SdkVersion : "2.1.0",
espressoSdkVersion : "2.2.2"
]
dependencies = [
//support
"appcompat-v7" : "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}",
"design" : "com.android.support:design:${version["androidSupportSdkVersion"]}",
"support-v4" : "com.android.support:support-v4:${version["androidSupportSdkVersion"]}",
"cardview-v7" : "com.android.support:cardview-v7:${version["androidSupportSdkVersion"]}",
"annotations" : "com.android.support:support-annotations:${version["androidSupportSdkVersion"]}",
"recyclerview-v7" : "com.android.support:recyclerview-v7:${version["androidSupportSdkVersion"]}",
"glide" : "com.github.bumptech.glide:glide:${version["glideSdkVersion"]}",
"retrofit" : "com.squareup.retrofit2:retrofit:${version["retrofitSdkVersion"]}",
"gson" : "com.google.code.gson:gson:2.8.1"
}
然后在project的build.gradle引入apply from: "config.gradle",moudle 的build.gradle的代碼如下
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
......
defaultConfig {
applicationId "com.example.tml.gradle.demo"
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode rootProject.ext.android["versionCode"]
versionName rootProject.ext.android["versionName"]
......
}
}
dependencies{
compile(rootProject.ext.dependencies["appcompat-v7"]) {
exclude module: 'support-annotations'
exclude module: 'support-v4'
}
compile(rootProject.ext.dependencies["design"]) {
exclude module: 'support-annotations'
exclude module: 'appcompat-v7'
exclude module: 'support-v4'
}
compile(rootProject.ext.dependencies["retrofit"]) {
exclude module: 'okhttp'
exclude module: 'okio'
}
compile(rootProject.ext.dependencies["retrofit"]) {
exclude module: 'okhttp'
exclude module: 'okio'
}
compile(rootProject.ext.dependencies["glide"]) {
exclude module: 'support-v4'
}
compile rootProject.ext.dependencies["gson"]
......
}
參考
http://wiki.jikexueyuan.com/project/deep-android-gradle/
http://avatarqing.github.io/Gradle-Plugin-User-Guide-Chinese-Verision/basic_project/README.html
https://docs.gradle.org/current/javadoc/
http://www.groovy-lang.org/api.html
https://developer.android.com/studio/releases/gradle-plugin.html
https://developer.android.com/studio/build/index.html?hl=zh-cn
https://juejin.im/entry/59476897da2f60006786029f
https://segmentfault.com/a/1190000004241503
