DSL

作者: Drew_MyINTYRE | 来源:发表于2020-12-06 12:45 被阅读0次

    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
    }
    
    

    相关文章

      网友评论

          本文标题:DSL

          本文链接:https://www.haomeiwen.com/subject/zrknwktx.html