Gradle 學習
Gradle是一個基于Apache Ant和Apache Maven概念的項目自動化構建工具误算。它使用一種基于Groovy的特定領域語言(DSL, domain-specific language )來聲明項目設置急凰,而不是傳統(tǒng)的XML瘟芝。
gradle是一個自動化工具碉碉。配置gradle時,使用的是Groovy語言锹淌。Groovy的語法與Java類似影所。
Gradle可以構建多個project,一個build.gradle
代表一個project赶袄,每個project包含多個task揽涮。每個task里面可以包含多個action。
構建過程分為三步:
- 初始化階段:創(chuàng)建 Project 對象饿肺,如果有多個build.gradle蒋困,也會創(chuàng)建多個project.
- 配置階段:在這個階段,會執(zhí)行所有的編譯腳本敬辣,同時還會創(chuàng)建project的所有的task雪标,為后一個階段做準備。
- 執(zhí)行階段:在這個階段溉跃,gradle 會根據(jù)傳入的參數(shù)決定如何執(zhí)行這些task,真正action的執(zhí)行代碼就在這里.
Groovy語法
在一些情況下村刨,可能需要我們自己定義task。而Gradle其實使用的是groovy語言撰茎,因此嵌牺,在定義task之前需要先了解groovy語法。而groovy與Scala、Kotlin語言一樣逆粹,都是一種JVM語言募疮。
閉包
閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures)僻弹,是引用了自由變量的函數(shù)阿浓。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外蹋绽。
使用閉包的groovy代碼
def hash = ["name":"Andy", "age":25]
hash.each{ key, value ->
println "${key} : ${value}"
}
沒用閉包的Java代碼
Map<String, String>map = new HashMap<String, String>();
map.put("name", "Andy");
map.put("age","20");
for(Iterator iter = map.entrySet().iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
System.out.println(entry.getKey() + " : " + entry.getValue());
}
雖然在迭代上使用閉包的機會最多芭毙,但閉包確實還有其他用途。因為閉包是一個代碼塊蟋字,所以能夠作為參數(shù)進行傳遞(Groovy 中的函數(shù)或方法不能這樣做)稿蹲。
類
Groovy 中可以像在 Java 代碼中一樣定義類扭勉。不過不需要使用 public
修改符鹊奖,而且還可以省略方法參數(shù)的類型。
例如涂炎,我們可以創(chuàng)建一個User類忠聚,它有姓名和年齡屬性。
class User{
def name
def age
}
與java不同的是唱捣,groovy會自動生成User類的getter和setter方法两蟀。
Groovy in Gradle
在配置文件中的apply plugin: 'com.android.application'
轉化為groovy語法為:
project.apply([plugin: 'com.android.application'])
apply()是Project類的方法,參數(shù)是map集合震缭。
build.gradle文件中的依賴配置赂毯。
dependencies {
compile 'com.google.code.gson:gson:2.3'
}
轉化為groovy語法為:
project.dependencies({
add('compile', 'com.google.code.gson:gson:2.3', {
// Configuration statements
})
})
構建Android項目
Gradle 和 Android 插件可以完成以下方面的構建配置:
- buildTypes:在模塊級
build.gradle
文件的android {}
代碼塊內(nèi)部創(chuàng)建和配置buildTypes。
android {
...
defaultConfig {...}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
}
/**
* The 'initWith' property allows you to copy configurations from other build types,
* so you don't have to configure one from the beginning. You can then configure
* just the settings you want to change. The following line initializes
* 'jnidebug' using the debug build type, and changes only the
* applicationIdSuffix and versionNameSuffix settings.
*/
jnidebug {
// This copies the debuggable attribute and debug signing configurations.
initWith debug
applicationIdSuffix ".jnidebug"
jniDebuggable true
}
}
}
- productFlavors:與配置buildTypes類似拣宰,將配置添加到
productFlavors {}
代碼塊中党涕。
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {
demo {
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
applicationIdSuffix ".full"
versionNameSuffix "-full"
}
}
}
Gradle 創(chuàng)建的Build Variants數(shù)量等于每個productFlavors中的Flavor數(shù)量與配置的buildTypes數(shù)量的乘積。
- dependencies:
dependencies {
// The 'compile' configuration tells Gradle to add the dependency to the
// compilation classpath and include it in the final package.
// Dependency on the "mylibrary" module from this project
compile project(":mylibrary")
// 遠程二進制依賴
compile 'com.android.support:appcompat-v7:27.1.1'
// Local binary dependency
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Gradle 與Android Gradle Plugin
Gradle作為一個異常強大的構建工具巡社,為了滿足不同平臺的需求膛堤,比如:Java平臺有Java構建邏輯,Android平臺有Android構建邏輯晌该。Gradle務必是要支持自定義構建的肥荔,這個功能正是由Gradle Plugin提供,而對應于Android工程的構建邏輯就是由Android Gradle Plugin實現(xiàn)的了朝群。
自定義Gradle插件
自定義插件的目錄結構
plugin
└── src
└── main
| ├── groovy
| | └── com
| | └── package
| | └── name
| └── resources
| └── META-INF
| └── gradle-plugins
|_ build.gradle
由上述插件結構可知燕耿,自定義插件大致可分為三個部分。groovy目錄姜胖,resources目錄和build.gradle配置文件誉帅。
build.gradle
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
implementation gradleApi()
implementation localGroovy()
}
META-INF/gradle-plugins
在META-INF/gradle-plugins 目錄下添加一個屬性文件,主要用來使得Gradle找到該插件。
implementation-class=com.nxiangbo.plugin.main.CustomPlugin
Groovy 目錄
為了創(chuàng)建Gradle插件堵第,我們必須創(chuàng)建一個實現(xiàn)Plugin
接口的類吧凉。當我們將自定義的插件應用到項目時,Gradle就會創(chuàng)建這個類的實例踏志,并調用這個類的apply()
方法阀捅。而project作為該方法的參數(shù),因此插件可以使用project的配置针余。下面我們在groovy目錄下創(chuàng)建CustomPlugin.groovy饲鄙。
class CustomPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
def extension = project.extensions.create("customPlugin", CustomExtension)
project.task("demo"){
project.afterEvaluate{
println("versionName=${extension.versionName} versionCode=${extension.versionCode}")
}
}
}
}
class CustomExtension {
String versionName
String versionCode
}
發(fā)布插件
只需要在build.gradle文件中添加uploadArchives task就可以將插件發(fā)布到本地。
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('D:/repo'))
}
}
}
}
應用插件
在需要使用該插件的項目中的build.gradle 文件中圆雁,添加如下代碼
apply plugin: 'customplugin'
customPlugin {
versionName='version'
versionCode='1.1.0'
}
Gradle插件調試
首先忍级,在Android Studio 中設置Edit Configurations -> +號 -> Remote -> 填寫Host和端口號
然后,運行gradle :app:clean -Dorg.gradle.debug=true --no-daemon