Gradle自有属性 &属性匹配优先级

120 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

Project 核心API

Project 提供了一系列操作 Project 对象的 API:

  • getProject(): 返回当前 Project;
  • getParent(): 返回父 Project,如果在工程 RootProject 中调用,则会返回 null;
  • getRootProject(): 返回工程 RootProject;
  • getAllprojects(): 返回一个 Project Set 集合,包含当前 Project 与所有子 Project;
  • getSubprojects(): 返回一个 Project Set 集合,包含所有子 Project;
  • project(String): 返回指定 Project,不存在时抛出 UnKnownProjectException;
  • findProject(String): 返回指定 Project,不存在时返回 null;
  • allprojects(Closure): 为当前 Project 以及所有子 Project 增加配置;
  • subprojects(Closure): 为所有子 Project 增加配置。

Project 属性 API

Project 提供了一系列操作属性的 API,通过属性 API 可以实现在 Project 之间共享配置参数:

  • hasProperty(String): 判断是否存在指定属性名;
  • property(Stirng): 获取属性值,如果属性不存在则抛出 MissingPropertyException;
  • findProperty(String): 获取属性值,如果属性不存在则返回 null;
  • setProperty(String, Object): 设置属性值,如果属性不存在则抛出 MissingPropertyException。

实际上,你不一定需要显示调用这些 API,当我们直接使用属性名时,Gradle 会帮我们隐式调用 property() 或 setProperty()。

例如:

build.gradle

name => 相当于 project.getProperty("name") 
project.name = "Peng" => 相当于 project.setProperty("name", "Peng")

属性匹配优先级

Project 属性的概念比我们理解的字段概念要复杂些,不仅仅是一个简单的键值对。

Project 定义了 4 种命名空间(scopes)的属性 —— 自有属性、Extension 属性、ext 属性、Task。 当我们通过访问属性时,会按照这个优先级顺序搜索。

getProperty() 的搜索过程:

  • 1、自有属性: Project 对象自身持有的属性,例如 rootProject 属性;
  • 2、Extension 属性;
  • 3、ext 属性;
  • 4、Task: 添加到 Project 上的 Task 也支持通过属性 API 访问;
  • 5、父 Project 的 ext 属性: 会被子 Project 继承,因此当 1 ~ 5 未命中时,会继续从父 Project 搜索。需要注意: 从父 Project 继承的属性是只读的;
  • 6、以上未命中,抛出 MissingPropertyException 或返回 null。

setProperty() 的搜索路径(由于部分属性是只读的,搜索路径较短):

  • 1、自有属性
  • 2、ext 额外属性
Extension扩展

就是之前文章我们讲的插件扩展,用于定义JavaBean或GroovyBean接受外界delegete传进来的属性

例如android{},之前讲的sourceSets{}源集等

ext属性

Gradle 为 Project 和 Task 提供了 ext 命名空间,用于定义额外属性。 如前所述,我们经常会在 Root Project 中定义 ext 属性,而在子 Project 中可以直接复用属性值,例如:

子 Project 会继承 父 Project 定义的 ext 属性,但是只读的。

项目 build.gradle

ext {  
  kotlin_version = '1.4.31'
}

模块 build.gradle

// 如果子 Project 也定义了 kotlin_version 属性,则不会引用父 Project 
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

Project 文件 API

文件路径
  • getRootDir(): Project 的根目录(不是工程根目录)
  • getProjectDir(): 包含 build 文件夹的项目目录
  • getBuildDir(): build 文件夹目录
文件获取
  • File file(Object path): 获取单个文件,相对位置从当前 Project 目录开始
  • ConfigurableFileCollection files(Object... paths): 获取多个文件,相对位置从当前 Project 目录开始
文件拷贝

copy(Closure): 文件拷贝,参数闭包用于配置 CodeSpec 对象

copy {
    // 来源文件
    from file("build/outputs/apk")
    // 目标文件
    into getRootProject().getBuildDir().path + "/apk/"
    exclude {
        // 排除不需要拷贝的文件
    }
    rename {
        // 对拷贝过来的文件进行重命名
    }
}
文件遍历

fileTree(Object baseDir): 将指定目录转化为文件树,再进行遍历操作

fileTree("build/outputs/apk") { FileTree fileTree ->
    fileTree.visit { FileTreeElement fileTreeElement ->
        // 文件操作
    }
}