Android Gradle 理解之Extension

在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 action) {
        this.extensionsStorage.configureExtension(name, action);
    }

可以看到主要调用了extensionsStorage这个类,点开extensionsStorage类,发现了很明显的一个map

  private final Map extensions = new LinkedHashMap();

看如下:


屏幕快照 2021-04-11 下午11.18.28.png

可以看到
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也有密不可分的连接,下篇文章详细讲下此类

你可能感兴趣的:(Android Gradle 理解之Extension)