我们先来看一个简单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对象配置