NamedDomainObjectContainer
顾名思义就是命名领域对象容器,它的主要功能有:
-
通过DSL创建指定type的对象实例
-
指定的type必须有一个public构造函数,且必须带有一个String name的参数
-
它是一个实现了SortedSet接口的容器,所以所有领域对象的name属性都必须是唯一的,在容器内部会用name属性来排序
Gradle 中有很多容器类的迭代遍历方法有 each(Closure action)、all(Closure action),但是一般我们都会用 all(...) 来进行容器的迭代。all(...) 迭代方法的特别之处是,不管是容器内已存在的元素,还是后续任何时刻加进去的元素,都会进行遍历。
buildTypes {}
defaultConfig {}
productFlavors{}
//上面的扩展函数就是这么来的
private final DefaultConfig defaultConfig;
private final NamedDomainObjectContainer<ProductFlavor> productFlavors;
private final NamedDomainObjectContainer<BuildType> buildTypes;
private final NamedDomainObjectContainer<SigningConfig> signingConfigs;
public void defaultConfig(Action<DefaultConfig> action) {
this.checkWritability();
action.execute(this.defaultConfig);
}
public void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) {
this.checkWritability();
action.execute(this.buildTypes);
}
public void productFlavors(Action<? super NamedDomainObjectContainer<ProductFlavor>> action) {
this.checkWritability();
action.execute(this.productFlavors);
}
public void signingConfigs(Action<? super NamedDomainObjectContainer<SigningConfig>> action) {
this.checkWritability();
action.execute(this.signingConfigs);
}
// android{}这么来的
//AppPlugin 就是插件 com.android.application 的实现类,
//LibraryPlugin 则是插件 com.android.library 的实现类,
//接着再看看 AppPlugin 里是怎样创建 Extension 的:
public class AppPlugin extends BasePlugin implements Plugin<Project> {
@Inject
public AppPlugin(Instantiator instantiator, ToolingModelBuilderRegistry registry) {
super(instantiator, registry);
}
protected BaseExtension createExtension(Project project, ProjectOptions projectOptions, Instantiator instantiator, AndroidBuilder androidBuilder, SdkHandler sdkHandler, NamedDomainObjectContainer<BuildType> buildTypeContainer, NamedDomainObjectContainer<ProductFlavor> productFlavorContainer, NamedDomainObjectContainer<SigningConfig> signingConfigContainer, NamedDomainObjectContainer<BaseVariantOutput> buildOutputs, ExtraModelInfo extraModelInfo) {
return (BaseExtension)project.getExtensions().create("android", AppExtension.class, new Object[]{project, projectOptions, instantiator, androidBuilder, sdkHandler, buildTypeContainer, productFlavorContainer, signingConfigContainer, buildOutputs, extraModelInfo});
}
public void apply(Project project) {
super.apply(project);
}
//省略...
}
def getInfo() {
//或者 直接 project.android
BaseExtension extension = project.extensions.getByName("android")
def android = project.extensions.getByType(AppExtension)
project.android
println "buildToolsVersion:${extension.buildToolsVersion}"
println "compileSdkVersion:${extension.getCompileSdkVersion()}"
println "applicationId:${extension.defaultConfig.applicationId}"
println "minSdkVersion:${extension.defaultConfig.minSdkVersion}"
println "targetSdkVersion:${extension.defaultConfig.targetSdkVersion}"
println "versionCode:${extension.defaultConfig.versionCode}"
println "versionName:${extension.defaultConfig.versionName}"
}
Instantiator
Instantiator 用于实例化对象, 使用Instantiator而不直接使用new,是因为使用Instantiator实例化对象时,会添加DSL特性
ExtensionContainer
它的作用就是通过实现自定义的 Extension,可以在 Gradle 脚本中增加类似 android 这样命名空间的配置,Gradle 可以识别这种配置,并读取里面的配置内容,一般我们通过ExtensionContainer来创建并管理Extension
/先定义一个普通的java类,包含2个属性
class Foo {
int age
String username
String toString() {
return "name = ${username}, age = ${age}"
}
}
//创建一个名为 foo 的Extension
getExtensions().create("foo", Foo)
//配置Extension
foo {
age = 30
username = "hjy"
}
task testExt.doLast {
//能直接通过 project 获取到自定义的 Extension
println project.foo
}
网友评论