在android的gradle的体系中,extension是很重要的一个知识点,可以说,理解了extension就能用语言的形式看待android.gradle文件了
首先我们都知道要给project赋值额外的属性,一般有两种方式
分别是gradle.properties和ext
例如
gradle.properties文件
PROJ_VERSION=0.0.1
# Automatically convert third-party libraries to use AndroidX
或者ext的写法
ext {
extA = "3"
}
说到这里可能就有疑惑了,那ext可以变成extension么,为何一定要是ext呢?
其实这就牵扯到extension了,我们换种写法可能更加清晰
getProject().extensions.configure("ext") {
org.gradle.internal.extensibility.DefaultExtraPropertiesExtension extProperties ->
extProperties.setProperty("extA", "3")
}
可以看到写法2其实等同于写法1,只不过在写法一简洁了很多而已
那我们具体分析下getProject().extensions到底是何东西
这里主要看下它的configure方法
public void configure(String name, Action super T> action) {
this.extensionsStorage.configureExtension(name, action);
}
可以看到主要调用了extensionsStorage这个类,点开extensionsStorage类,发现了很明显的一个map
private final Map extensions = new LinkedHashMap();
看如下:
可以看到
ext就是一开始存放的建,其值就是上文中说的DefaultExtraPropertiesExtension对象,
举个例子
def testExtension = getExtensions().create("test1", TestExtension, project)
这里我创建了test1的健,其值就是设定的TestExtension,至于上文中的setProperty方法,只不过是只不过是DefaultExtraPropertiesExtension这个对象的方法,当然,里面很明显保存了一个map来存放数据,可以看到
你在gradle.properties的简值对和ext的写法都保存在了这个map中
//DefaultExtraPropertiesExtension
@Override
public void setProperty(String name, @Nullable Object newValue) {
if (name.equals("properties")) {
throw new ReadOnlyPropertyException("name", ExtraPropertiesExtension.class);
}
set(name, newValue);
}
@Override
public void set(String name, @Nullable Object value) {
storage.put(name, value);
}
这样一目了然了,当然在android.gradle中,也用类似的方法创建了android的标签
//AbstractAppPlugin
@NonNull
@Override
protected BaseExtension createExtension(
@NonNull Project project,
@NonNull ProjectOptions projectOptions,
@NonNull GlobalScope globalScope,
@NonNull NamedDomainObjectContainer buildTypeContainer,
@NonNull NamedDomainObjectContainer productFlavorContainer,
@NonNull NamedDomainObjectContainer signingConfigContainer,
@NonNull NamedDomainObjectContainer buildOutputs,
@NonNull SourceSetManager sourceSetManager,
@NonNull ExtraModelInfo extraModelInfo) {
return project.getExtensions()
.create(
"android",
getExtensionClass(),
project,
projectOptions,
globalScope,
buildTypeContainer,
productFlavorContainer,
signingConfigContainer,
buildOutputs,
sourceSetManager,
extraModelInfo,
isBaseApplication);
}
可以看到android的标签在初始化plugin的时候被创建出来,这里有牵扯到了NamedDomainObjectContainer类,其实这个和extension也有密不可分的连接,下篇文章详细讲下此类