赞
踩
就是 Gradle 的 Extension,翻译成中文意思就叫扩展。它的作用就是通过实现自定义的 Extension,可以在 Gradle 脚本中增加类似 android 这样命名空间的配置,Gradle 可以识别这种配置,并读取里面的配置内容。
一般我们通过ExtensionContainer来创建Extension,这个类跟TaskContainer命名有点类似。TaskContainer是用来创建并管理Task的,而ExtensionContainer则是用来创建并管理Extension的,通过Project的以下API可以获取到ExtensionContainer对象
ExtensionContainer getExtensions()
<T> T create(String name, Class<T> type, Object... constructionArguments)
<T> T create(Class<T> publicType, String name, Class<? extends T> instanceType, Object... constructionArguments)
//在project中添加一个名为groupId的属性 project.ext.groupId = "groupId" // 使用ext块添加扩展属性 ext { versionExt = "1.0.2" email = "test@gihhub.com" artifactId='EasyDependency' config=[ key:'value' ] android = [compileSdkVersion : 25, buildToolsVersion : '25.0.0', applicationId : 'com.youdu', minSdkVersion : 16, targetSdkVersion : 23, versionCode : 1, versionName : '1.0.0'] signConfigs = ['storeFile' : 'abc.jks', 'storePassword': '123456', 'keyAlias' : 'abc', 'keyPassword' : '123456'] dependence = ['libSupportV7' : 'com.android.support:appcompat-v7:25.0.0', 'libSupportMultidex' : 'com.android.support:multidex:1.0.1'] } //打印各个扩展属性 task extParams { println versionExt + " " + email println android.each { it.key + it.value } println dependence.each { it.key + it.value } } //创建自定义Extension class MyDefaultConfig { String applicationId String versionCode String versionName int targetSdkVersion @Override String toString() { return "applicationId = $applicationId , versionCode = $versionCode, versionName = $versionName, targetSdkVersion = $targetSdkVersion" } } //创建一个名为 myDefaultConfig 的Extension,每个 Extension 实际上与某个类是相关联的 getExtensions().create("myDefaultConfig", MyDefaultConfig) //配置extention myDefaultConfig { //myDefaultConfig里面能配置的属性与类 MyDefaultConfig 中的字段是一致的 applicationId = "com.example" versionName = "1.0.1" versionCode = "1" targetSdkVersion 31 } task taskExt { //能直接通过 project 获取到自定义的 Extension println project.myDefaultConfig } //打印 applicationId = com.example , versionCode = 1, versionName = 1.0.1, targetSdkVersion = 31 //父类 class Animal { String username int legs Animal(String name) { username = name } void setLegs(int c) { legs = c } String toString() { return "This animal is $username, it has ${legs} legs." } } //子类 class Pig extends Animal { int age String owner Pig(int age, String owner) { super("Pig") this.age = age this.owner = owner } String toString() { return super.toString() + " Its age is $age, its owner is $owner." } } //创建的Extension是 暴露出来Animal 类型,创建extension名称是name,该extension的类型是Pig,后面2个是参数 def aAnimal = getExtensions().create(Animal, "animal", Pig, 5, "pege") //创建的Extension是 Pig 类型 def aPig = getExtensions().create(Pig, "pig", Pig, 3, "joge") animal { //注:自定义扩展和属性没有提示 legs = 4 //扩展属性配置对象值 } pig { setLegs(2) } task animalExt { println aAnimal println aPig }
什么是NamedDomainObjectContainer?
顾名思义就是命名领域对象容器,它的主要功能有:
NamedDomainObjectContainer 需要通过 Project.container(…) API 来创建,其定义为:
NamedDomainObjectContainer container(Class type)
NamedDomainObjectContainer container(Class type, NamedDomainObjectFactory factory)
NamedDomainObjectContainer container(java.lang.Class type, Closure factoryClosure
需要完成此种嵌套扩展属性定义:
android { buildTypes { release { // 是否开启混淆 minifyEnabled true // 开启ZipAlign优化 zipAlignEnabled true //去掉不用资源 shrinkResources true // 混淆文件位置 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 使用release签名 signingConfig signingConfigs.hmiou } debug { signingConfig signingConfigs.hmiou } } }
// NamedDomainObjectContainer //这是领域对象类型定义 class TestDomainObj { //必须定义一个 name 属性,并且这个属性值初始化以后不要修改 String name String msg //构造函数必须有一个 name 参数 public TestDomainObj(String name) { this.name = name } void msg(String msg) { this.msg = msg } String toString() { return "name = ${name}, msg = ${msg}" } } //创建一个扩展 class TestExtension { //定义一个 NamedDomainObjectContainer 属性 NamedDomainObjectContainer<TestDomainObj> testDomains public TestExtension(org.gradle.api.Project project) { //在构造函数中通过 project.container(...) 方法创建 NamedDomainObjectContainer testDomains = project.container(TestDomainObj) } //让其支持 Gradle DSL 语法,注:该方法名要与Extension第二层的name一致 void buildTypes(Action<NamedDomainObjectContainer<TestDomainObj>> action) { action.execute(testDomains) } void test() { //遍历命名领域对象容器,打印出所有的领域对象值 testDomains.all { println(it) } } } //创建一个名为 test 的 Extension def testExt = getExtensions().create("myandroid", TestExtension, project) //该第三个参数project就传到TestExtention对象的构造参数中 //给 TextExtention对象配置 NamedDomainObjectContainer 属性 myandroid { buildTypes { release { msg "This is release config" } debug { msg "This is debug config" } } } task nameDomainTask { testExt.test() //执行TextExtention对象的test方法,打印配置的各个属性 //domainx配置就成为了默认、必须的name属性 内部配置了msg属性 } //打印 //name = debug, msg = This is debug config //name = release, msg = This is release config
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。