前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gradle Builds Everything —— Task 实例

Gradle Builds Everything —— Task 实例

作者头像
程序亦非猿
发布2019-11-23 08:42:14
7150
发布2019-11-23 08:42:14
举报
文章被收录于专栏:程序亦非猿程序亦非猿

本文开始讲述下 Task 是如何定义的。

为了方便,我们的语境分不开 GradleAndroidGradlePlugin,因此此处不脱离 Android环境来介绍 Gradle。我们在讲述任务依赖的时候,提到一个 Manager的东西,在这里,我们说到的是 AndroidGradlePlugin提供的 BuildableArtifactsHolder这个类。

一个 Task 如果有有意义的输出,且产物可能被其他的 Task 所使用的时候,我们可以往 BuildableArtifactsHolder注册我们的产物,注册方式有这么几种:

createBuildableArtifact/createDirectory/createArtifactFile

这些 api 需要传入创建文件的类型,文件的文件名,动作等,以 createArtifactFile的其中一种形式为例:

代码语言:javascript
复制
fun createArtifactFile(        artifactType: ArtifactType,        operationType: OperationType,        taskName: String,        fileName: String) : Provider<RegularFile>

artifactType 就是产物类型

operationType 是操作类型,可以是初始化(init),追加(append),或者变化(transform),区别如下:

  1. 如果指明了是 init,那么它之前不可以有任何针对相同产物类型的调用
  2. 如果指明了是 append,那么是追加相关的文件
  3. 如果指明了是 transform,那么就是替换当前的文件。

你可以根据你使用产物的目的来使用不同类型,因为返回值是一个 FileCollection (文件集合,不是文件夹的概念),如果调用的是 transform,你需要注意在 Configuration 阶段对于这些产物调用顺序的问题,如果 B.transform 在 A.transform 之后,那么获取最终产物的时候,就会取走 B 的结果。

BuildableArtifactsHolder 提供的 api 一般都已经让你传入了 taskName,就是让你告诉它,你所产生的产物由哪个任务生成。后续你去根据 artifactType 获取产物(FileCollection)的时候,它会检查这个任务是否执行,如果没有的话会先执行,这部分判断的逻辑由 FileCollection 的 builtBy 做到,由 Gradle 进行管理。

Task 的配置

以上,我们介绍了如何让 Task 的产物和 Task 本身产生一些关联,这种关联建立完成之后,可以看到 createArtifactFile 这个函数的返回值是 Provider<RegularFile>,这里代表了一个目的地,我们往这个文件里写入的产物即可;当然这里也可以创建文件夹同理,示例代码:

代码语言:javascript
复制
task.outputFile =  variantScope.getArtifacts().createArtifactFile(                    InternalArtifactType.BUNDLE,                    BuildArtifactsHolder.OperationType.INITIAL,                    taskName,                    bundleName)

然后在 task 定义的地方:

代码语言:javascript
复制
class Task {
 private Provider<RegularFile> outputFile;
 @OutputFile public Flie getOutputFile() {    return outputFile.get().asFile(); }
}

这样的话,gradle 会自动帮你创建这个文件,开发者需要的只是调用 getOutputFile()拿到 File然后写入即可。

Task 的联动

我们知道了 Task 产生一个文件的完整流程,我们该如何使用这个文件呢?我们在另外一个 Task 中,定义一下 input

代码语言:javascript
复制
task.input = variantScope.getArtifacts().getArtifactFiles(type); //这里的 type 和上面的type一样,比如 InternalArtifactType.BUNDLE

这个拿到是一个 BuildableArtifact 对象,它的声明如下:

代码语言:javascript
复制
interface BuildableArtifact : Iterable<File>, Buildable, Supplier<FileCollection> {    val files : Set<File>    fun isEmpty() : Boolean}

可以使用 get()获取一个 FileCollection,当再次调用 FileCollection.getFiles()方法时,gradle 就会检查产生这个产物的 Task 是否已经执行,如果没有执行,就会先执行前面一个 Task

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序亦非猿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Task 的配置
  • Task 的联动
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档