还在用build.gradle吗?试试build.gradle.kts吧

2022-03-06 09:41:22 浏览数 (1)

theme: smartblue

前言

虽然大家都写了很多年的安卓了,我之前一直都有对于build.gradle有点疑惑和不解(这部分其实已经没有了)。就比如为啥androidandroid?还有dependencies是啥?apply formapply plugin有什么区别。

还是先说下Groovy吧,还是老生常谈我并不喜欢我Groovy,但是有时候我觉得Groovy也还是非常不错的。

 Groovy是Java虚拟机的敏捷和动态语言,以Java语言的优势为基础,添加了从Python、Ruby和Smalltalk等语言中借鉴的特性。提供流行的编程语言特性,学习成本几乎为零。提供静态类型检查的能力,并静态地编译成java字节码,以获得健壮性和性能,与所有现有的Java类和库无缝集成,可以在任何可以使用java的地方使用它。通过其强大的处理原语、OO能力和Ant DSL使编写shell和构建脚本变得容易。在开发Web,GUI,数据库或控制台程序时通过减少框架性的代码大大提高了开发者的效率。支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于阅读和维护。并且支持单元测试,可以简化测试。

build.gradle和我们的编译息息相关,而且编译相关的对于一个安卓开发其实还是非常重要,而且也是息息相关的。Groovy的动态化也是有取舍的,下面我略列下我在开发过程中碰到的问题吧。

  1. 因为是一门动态语言而且也没有强类型判断,所以并不会出现编译报错,只会运行到对应代码的时候才出现问题。
  2. 没有任何语法提示,很多时候除了系统生成那部分代码,我们的学习成本和调试成本其实非常高。
  3. 只有你足够强足够牛逼的情况下,你可以通过remote的方式调试build.gradle,之后跟踪AGP的源代码,发现有那些可以更改的点。

在写Gradle脚本的时候,最痛苦的莫过于没有任何提示,唯一的调试手段就是使用print方法打印调试日志。如果我们能使用Kotlin编写Gradle脚本的时候,你会发现一切都变得有趣起来,嘴角开始微微上扬。

Gradle Kotlin DSL 1.0 Gradle官方其实在18年底就已经正式发布了kts的第一个版本了。那么话不多,为什么我们不试试呢。

正文开始

要安利大家学新东西那么就最好先给大家一点甜头,我有糖尿病我先来滋醒大家。

  1. 代码提示,kts内所有都是基于kotlin代码规范的,所以强类型语言的好处就是编译没通过的情况下,你根本无法运行。
  2. 源代码查看,原来Groovyblock其实在kts都是由拓展函数实现的,所以我们能直接看到传入的类是什么,以及这个类有哪些参数以及方法。举个例子Androidblock块内的参数我就都能看懂了。
  3. 混编以及热重载,kts能和gradle能同时编译,这样就可以让新的东西往新的架构上迁移,而旧的那部分就可以不动了,这样岂不是美滋滋。

我们先看一段代码吧

我们先来对比下两个基本内容相同的配置文件吧。

第一个是我截取的kts相关的,第二个则是我以前的一个项目采用的还是build.gradle。从第一眼的影像中,我们可以简单的比对出kts相关的代码提示上真的就会好很多。

举个例子各位大佬以前知道com.android.library中的android所代表的Extension到底是什么吗?那么和com.android.application下的有什么不同吗?我想知道他们的源代码在哪里怎么办?

灵魂三问之后我想问下各位有没有啥自己的看法哦,起码我在之前就算使用remote调试插件的时候,我也是靠猜测的方式去定位android所代表的Extension的。所以我在这边想要的出来的结论就是,如果你对安卓的编译感兴趣的情况下,可以先试试从kts开始反向推倒下每个字段所代表的含义是什么?

kts中,我发现com.android.application下的androidExtensionBaseAppModuleExtension,我们所有定义的子属性其实都是在这个实体类上的拓展而已,而com.android.library中的则是另外一个实现类LibraryExtension,相对而言他的字段属性就会更少一点,有兴趣的大佬可以自行跟踪翻查源代码。

虽然我在使用kts之前就知道了,因为自定义plugin的时候也会有对这部分的操作和使用。可以参考下逮虾户X,哈哈哈。

这部分内容其实在你编写自定义Plugin的时候还是有很大概率会使用到的,比如你的插件可以根据applicationId进行不同的代码生成变化。

这里我小展开下,大家不知道有没有想过implementation内的exclude和禁止依赖传递的transitive到底是什么?

这里我就给大家买个关子,有兴趣的大佬可以转化下kts,自己跟踪路径,看看其中到底都是些什么东西啊。

但是kts一定就比gradle好吗?我个人看法并不是啊,在最新的as中,其实对于gradle的源码跟踪其实就已经非常不错了。还有就是相比较而言,因为groovy是一门动态化语言,所以其中的类型判断也更为简单,而且groovy中的MethodMissing这个机制,可以帮助我们动态调用很多隐藏的api。

但是恰恰也就是因为这些对应的机制,有时候也会让开发无从入手,因为也不是别的啥,就是菜看不懂呀!!而kts则有一个更有优势的地方就是代码提示了!!!

还有一点就是kts,对于ext的支持简直堪称地狱,如果你有定义在全局的类似dep配置相关的,这部分改动真的可能要了你的老命。

这部分是真的完全比不上groovy,如果有除了用buildSrc这种方式解决了的大佬,可以告诉我下,让我学习一下啊!!!

那么还有必要学习吗?

我最近的感觉就是开发还是可以多尝试一些新鲜的东西的,特别是这种东西如果不会破坏当前既有结构,而且能完美并存的东西,其实都可以去尝试下。

毕竟现在这个情况吧,你比别人多会一点相对来说还是有些好处的。而且我个人看法就是稍微多掌握点这个能帮助各位老哥更好的了解和学习编译流程相关的内容。

另外事先声明,今天这篇文章吧,我觉得也就是一篇水文,就是给大家安利下我觉得有意思的东西,并没有实际太多的干货内容。

0 人点赞