Android Gradle之File操作+自定义Extension

File相关操作代码:
//Project.file() 方法能够相对项目目录定位一个文件
task filePosition {
    
    
    File configFile = file('mountains.xml')
    configFile = file(configFile.absolutePath)
    println(configFile.absolutePath)
    configFile = file(new File('src/build/config.xml'))
    configFile.mkdirs()
    println(configFile.absolutePath)
}

//根据一个 XML ,在build/generated下生成多个输出文件
task transform {
    
    
    def srcFile = file('mountains.xml')
    def destDir = new File(buildDir, 'generated')
    doLast {
    
    
        println "transforming source file."
        destDir.mkdirs()
        def mountains = new XmlParser().parse(srcFile) //解析mountains.xml文件得到节点
        mountains.children().each {
    
    
            def name = it.name()
            def destFile = new File(destDir, "${name}.txt")
            destFile.text = "$name"
        }
    }
}


//读写gradle.properties文件属性
task propertiesWrite {
    
    
    def defaultProps = new Properties()
    def propertiFile = new File(rootDir, "gradle.properties") //根目录下gradle.properties文件
    def inputStream = propertiFile.newDataInputStream()
    defaultProps.load(inputStream)  //Properties读取文件流

    defaultProps.setProperty("version", "1.1.0") //properti设置新属性
    def version = defaultProps.getProperty("version")  //properti读取新属性

    println("当前配置 version: " + version)
}
//打印  当前配置 version: 1.1.0

//创建文件集合,使用 FileCollection 接口表示文件集合
task collections {
    
    
    FileCollection collection = files('src/file1.txt', new File('src/file2.txt'), 'src/file3.txt')
    collection.each {
    
    
        println(it.absolutePath)
    }
    def files = collection.files //文件集合转set
    def list = collection as List //文件集合转list
    def union = collection + file('src/file4.txt')
    def different = collection - file('src/file3.txt')
}

//使用标准输出写入log信息
task loggerTask {
    
    
    logger.error("error message")
    logger.info("info message")
    logger.warn("warn message")
    logger.debug("debug message")
    logger.quiet("An info log message which is always logged.")
    logger.lifecycle("A lifecycle info log message.")
}

//文件树形操作
task fileTree {
    
    
    FileTree tree = fileTree('src/main/res')

    //遍历访问文件树的元素
    tree.visit {
    
     element->
        println "$element.file"
    }
}

//复制文件,任务类型为Copy,Copy类的父类定义好了from 和 into函数
task copyTask(type: Copy) {
    
    
    //因为在copy类型的task下,所以能直接用该task下的函数
    //包括函数 from to rename fileter等
    from('src/main/java')  //添加要复制的文件
    from('mountains.xml') //继续添加要复制的文件
    from file('src/main/res') //继续添加要复制的文件

    into('src/copyPath') //into表示要拷贝到的文件路径

//    rename { fileName ->  //文件重命名
//        fileName.relace('','')
//    }
}

Gradle之自定义Extension

Extension

就是 Gradle 的 Extension,翻译成中文意思就叫扩展。它的作用就是通过实现自定义的 Extension,可以在 Gradle 脚本中增加类似 android 这样命名空间的配置,Gradle 可以识别这种配置,并读取里面的配置内容。

一般我们通过ExtensionContainer来创建Extension,这个类跟TaskContainer命名有点类似。TaskContainer是用来创建并管理Task的,而ExtensionContainer则是用来创建并管理Extension的,通过Project的以下API可以获取到ExtensionContainer对象

ExtensionContainer getExtensions()

ExtensionContainer主要api及用法
<T> T create(String name, Class<T> type, Object... constructionArguments)
<T> T create(Class<T> publicType, String name, Class<? extends T> instanceType, Object... constructionArguments)

  • publicType:创建的 Extension 实例暴露出来的类类型;
  • name:要创建的Extension的名字,可以是任意符合命名规则的字符串,不能与已有的重复,否则会抛异常;
  • instanceType:该Extension的类类型;
  • constructionArguments:类的构造函数参数值
相关代码示例:
//在project中添加一个名为groupId的属性
project.ext.groupId = "groupId"

// 使用ext块添加扩展属性
ext {
    
    
    versionExt = "1.0.2"
    email = "[email protected]"
    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
}

嵌套Extension : NamedDomainObjectContainer

什么是NamedDomainObjectContainer?

顾名思义就是命名领域对象容器,它的主要功能有:

  • 通过DSL创建指定type的对象实例
  • 指定的type必须有一个public构造函数,且必须带有一个String name的参数
  • 它是一个实现了SortedSet接口的容器,所以所有领域对象的name属性都必须是唯一的,在容器内部会用name属性来排序

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开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

图片

猜你喜欢

转载自blog.csdn.net/weixin_43440181/article/details/134617785
今日推荐