我們先來看一個簡單app的build.grdle的定義
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.harish.test.sample"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
signingConfigs {
release {
storeFile file('keys/test.jks')
storePassword '123'
keyAlias 'mainkey'
keyPassword '123'
v2SigningEnabled true
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
debuggable true
jniDebuggable true
}
}
}
dependencies {
api fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
}
我們可以認爲build.gradle文件的內容,是以閉包的形式被執行的,這個閉包的delegate是project,先看project的類繼承信息
@HasInternalProtocol
public interface Project extends Comparable<Project>, ExtensionAware, PluginAware {
***
}
從繼承信息可以看出,project支持extension和plugin
重新回到build.gradle,dependencies是調用project的函數,apply則是應用插件,android則是一個extension
接着重點講講extension,project是ExtensionAware的,就說明其可以創建extension
project.extensions.create('android', AppExtension)
創建成功後,可以有兩個方式訪問extension對象
//通過project屬性
project.android.*** =
//通過namespace method
project.android{
}
build.gradle明顯使用的是第二種,android extension裏頭的配置,明顯都是函數調用,有些是直接配置值的,比如
compileSdkVersion 28
buildToolsVersion '28.0.3'
有些傳得則是閉包
defaultConfig {
versionName "1.1"
versionCode 104
targetSdkVersion 28
applicationId "com.harishhu.replugin.sample.demo1"
minSdkVersion 15
multiDexEnabled false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
如果要傳入閉包,則函數定義的最後一個參數,必須是Closure或者Action,比如:
//配置
repositories {
flatDir {
dirs 'libs'
}
}
//對應函數定義
/**
* <p>Configures the repositories for this project.
*
* <p>This method executes the given closure against the {@link RepositoryHandler} for this project. The {@link
* RepositoryHandler} is passed to the closure as the closure's delegate.
*
* @param configureClosure the closure to use to configure the repositories.
*/
void repositories(Closure configureClosure);
//配置
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//對應函數定義
public void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) ;
那Closure和Action有什麼區別?個人覺得最大的區別是,光從函數的定義,Closure是無法知曉閉包的運行作用域的,必須在函數註釋裏給予描述,比如repositories就說明了,閉包的delegate是RepositoryHandler
但是Action則不一樣,先看Action的定義
public interface Action<T> {
/**
* Performs this action against the given object.
*
* @param t The object to perform the action on.
*/
void execute(T t);
}
這是個模版接口,T則明確指明瞭閉包運行時的附屬對象類型,繼續拿build types舉例
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
minifyEnabled false
}
}
接着看buildTypes函數實現
public void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) {
checkWritability();
action.execute(buildTypes);
}
buildTypes即閉包執行的附屬對象,execute執行完後,相當於在buildTypes添加了屬性名分別爲release和debug兩個BuildType對象配置