稀土掘金 稀土掘金

AGP正确使用dependsOn

什么时候应该使用dependsOn?

简而言之,Gradle 通过计算任务依赖关系图来工作。假设您要构建一个 JAR 文件:您要调用 jar 任务,而 Gradle 将确定构建 jar,它需要编译类、处理资源等……确定任务依赖项,也就是说还需要执行哪些其他任务,是通过查看3个不同的东西来完成的:

任务取决于依赖项。例如,assemble.dependsOn(jar) 表示如果运行assemble,那么jar任务必须先执行

任务传递依赖关系,在这种情况下,我们不是在谈论任务,而是在谈论“出版物”。例如,当你需要编译项目 A 时,你需要在 classpath 项目 B 上,这意味着运行 B 的一些任务。

最后但并非最不重要的是,任务输入,也就是说,它需要什么来执行它的工作

看看下面的代码: image.png

用与其他构建工具(如 Maven 或 Ant)相同的方式思考是很诱人的,尤其是当您不习惯 Gradle 时。你在想“有一个任务,jar,它基本上将它在 classes/groovy/main 中找到的所有内容打包,所以如果我想在 jar 任务中添加更多内容,让我们在 classes/groovy/main 中添加更多内容” .

由于不同的原因,这是错误的,最明显的是:

当 docsFilesJar 任务将被执行时,它会向“classes”目录贡献更多文件,但是,等等,那些不是我们放在那里的类,对吧?它只是一个罐子,资源。我们不应该改用 resources/groovy/main 吗?或者是classes/groovy/resources?要不然是啥?好吧,你不应该关心,因为你不关心 Java 编译任务将其输出放在哪里!

它破坏了可缓存性:Gradle 有一个构建缓存,多个任务贡献于同一个输出目录是破坏缓存的典型示例。事实上,它打破了各种最新的检查,也就是说,Gradle 能够理解它不需要在没有任何变化的情况下执行任务。

它对 Gradle 是不透明的:上面的代码在 doLast 块中执行一个副本。没有什么能告诉 Gradle “类”有额外的输出。

想象另一个只需要类的任务。根据它执行的时间,它可能包含也可能不包含它不关心的 docsFileJar。这使得构建不可重现(请注意,这正是 Maven 构建不可信并且您需要运行干净的原因,因为任何“目标”可以随时写入任何目录,因此无法推断谁贡献了什么)。

它需要声明 jar 任务和 docsFileJar 任务之间的显式依赖关系,以确保如果我们执行 jar,我们的“docs jar”文件存在

它没有说明为什么会有依赖关系:是因为你想订购东西,还是因为你需要依赖任务产生的工件?还有什么?

很容易忘记这些:因为您可能经常运行构建,您可能认为您的构建工作,因为 jar 是任务图的一部分,并且偶然地,docsFileJar 会在之前执行

它会产生意外的额外工作:大多数情况下,dependsOn 会触发过多的工作。 Gradle 是一个智能构建工具,它可以精确计算每个特定任务需要执行的内容。通过使用dependsOn,你有点像使用锤子并强迫它在图中整合一些不必要的东西。简而言之:你做的工作太多了。

很难摆脱它们:当您看到dependsOn时,因为它没有说明为什么需要它,因此在优化构建时通常很难摆脱这种依赖关系

改用隐式依赖!

我们的问题的答案实际上更容易推理:颠倒逻辑。与其想“我应该把这些东西放在哪里,以便被 jar 拾取”,不如想想“让我们告诉 jar 任务它也需要拾取我的资源”。

总而言之,这是关于正确声明您的任务输入。

与其修补另一个任务的输出(说真的,忘记这个!),每个任务都必须被认为是一个接受输入并产生输出的函数:它是隔离的。那么,我们的 docsFileJar 的输入是什么?我们要打包的资源。它的输出是什么?罐子本身。没有关于我们应该把罐子放在哪里的问题,我们让 Gradle 为我们选择了一个合理的地方。

那么 jar 任务本身的输入是什么?好吧,这是常规输入加上我们的 jar。它更容易推理,而且作为奖励,它甚至更短!

因此,让我们将上面的代码重写为:

image.png

您看得出来差别吗?我们摆脱了 docFilesJar 任务中的副本,我们不想这样做。相反,我们想要的是说“当你构建 jar 时,还要选择这个 docsFileJar。这就是我们通过 docsFileJar 告诉我们正在做的事情。Gradle 足够聪明,知道它什么时候需要执行 jar 任务,首先,它需要构建 docsFilesJar。

这样做有几个优点:

  • 依赖变得隐含:如果我们不想再包含 jar,我们只需将其从输入规范中删除即可。
  • 它不会污染其他任务的输出
  • 可以独立于 jar 执行 docsFileJar
  • 总而言之,这是为了将事物彼此隔离并降低意外破坏构建的风险!

上面的代码可以工作,但它有一个缺点:即使我们调用不需要的东西,docFilesJar 和 jar 任务也会被配置(实例化)。例如,假设您调用 gradle compileJava:没有理由在那里配置 jar 任务,因为我们不会执行它们。

image.png

作为结论:

尽可能避免使用显式的dependsOn

我倾向于说dependsOn唯一合理的用例是生命周期任务(生命周期任务是目标只是“组织构建”的任务,例如构建,组装,检查:他们自己不做任何事情,他们只是将一些家属绑定在一起)

如果您发现用例不是生命周期任务并且不能通过隐式任务依赖项来表达(例如声明输入而不是依赖项),则将其报告给 Gradle 团队

玻璃钢生产厂家台州玻璃钢花盆陕西玻璃钢骆驼雕塑玻璃钢人像雕塑多少钱韶关玻璃钢雕塑批发在邯郸哪里有玻璃钢花盆卖节庆商场美陈北京方形插花玻璃钢花盆重庆商场节日活动美陈布置吉林公园玻璃钢雕塑设计商场秋季美陈大门效果图玻璃钢人物雕塑资讯深圳玻璃钢花盆销售厂家玻璃钢交警雕塑玻璃钢雕塑哪家买批发玻璃钢雕塑正规玻璃钢雕塑厂家承诺守信广州玻璃钢公园人物雕塑通化沈阳玻璃钢花盆张家口玻璃钢商场美陈陕西玻璃钢浮雕泡沫雕塑厂家餐厅商场橱窗美陈河北玻璃钢雕塑摆件报价南宁玻璃钢雕塑生产商玻璃钢雕塑裂了玻璃钢骆驼雕塑哪家好大理市玻璃钢雕塑价格代理玻璃钢奶牛雕塑园林景观校园玻璃钢景观雕塑红旗玻璃钢雕塑价格商场ip美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化