飞雪无情:Android Gradle 技巧实践解析

2017年2月23日周四晚8点30分,今晚的分享话题是“Android Gradle 必备实用技巧”,分享人是《Android Gradle权威指南》的作者飞雪无情(李帅)老师。李帅老师是一位资深的Android开发工程师,著有《Android Gradle权威指南》,同时还是Android官方技术文档的一名译者。以下是主持人jacty整理的实录,记录下了作者和读者问答的精彩片段。


问:gradle、groovy、DSL 它们之间是什么关系?可以举个例子吗?

:的确有点容易混淆,我们一个个谈。

Groovy是基于JVM虚拟机的动态语言,基于Java,又完全兼容Java,但是添加了很多灵活的动态类型和特性,使用很方便。如果有Java基础,入门Groovy很快。

DSL(Domain Specific Langage),领域特定语言。是针对某一特定领域,开发的,有一定限制的计算机语言,目的性很强。有不少语言可以用来开发DSL,比如Groovy,但是又不是所有都行,得具有几个条件,比如要使动态语言,支持闭包,可以直接执行脚本等等。

说了这两个 Gradle就很好理解啦。Gradle,就是使用Groovy这门语言开发的,专门用于构建的DSL。


问:很想知道在电脑资源有限情况下,如何加速编译,比如插件优化等?

:Gradle有时候是比较慢,这取决于你使用的插件,构建的项目等。在资源有限的情况下呢,可以从以下几个方面提速。

启用gradle daemon,在gradle.properties里配置org.gradle.daemon=true即可启用。这是Gradle的守护进程。启动后,就不用每次构建的时候都重新启动了,可以提速。

第二个办法是启用并行构建,org.gradle.parallel=true,也是在gradle.properties配置。

第三个办法是:减少项目依赖,把项目的源代码依赖,变成jar,aar这样的依赖,这样构建的时候不用每个项目都去构建了。

第四个是:给Gradle尽可能分配多一些内存。JVM分配内存,这个大家都知道。

第五个是:尽可能使用较新的版本,因为他们会做一些优化。


问:DSL 不是指一种具体的语言?而更像是一种规范?可以这样理解吗?

:可以的,这么理解,可能更容易一些,不过他也是一种语言,是一个和特定领域沟通的载体,是受限的语言。


问:使用 jenkins 自动打包的时候如果因为项目太大而没有拉取所有的历史版本,这时使用 tag 数量来作为版本号还适用吗?

:tag的数量是一种一个方法,所以对tag的要求比较高,如果tag不全,就不适用了。可以采用其他办法,比如时间戳进行二次换算;自定义的计数器等等都可以达到目的。tag数量只是我举的一个例子,大家可以作为参考。可以用你喜欢的,容易的方式。其实就是保持一个计数器,不停的增加它,就可以了。非开发也能去打包,计数器可以存储到数据库里,也很方便。


问:问个小问题,mac 上有什么好用的 groovy 的ide 工具没,让后没有有什么比较好的练手项目?

:其实做Android开发,一般都会使用Android Studio,AS是基于IDEA二次开发的,这个时候比较推荐你还用IDEA,它有Groovy的插件,可以直接使用,方便开发。我调试Gradle的源代码,也是这么做的。如果你刚入门呢,练手的项目可以使用Java的,不过你可以采用Groovy的写法。比如Map的遍历,Java很复杂,你可以采用Grrovy的each闭包就可以达到。然后推荐一本书,《Groovy程序设计》。国外大牛的,可以让你很快入门,因为你有Java基础。Groovy是Java的超集哦。

我前两天写了两篇关于这方便的文章,可以关注我的公众号flysnow_org查看,一篇是《Gradle必备——Groovy基础》,一篇是《Groovy闭包和DSL》。


问:我们项目中,经常涉及到升级gradle插件后,出现各种问题,比如,从2.2.3升级到2.3之后,databinding老是报错,这种怎么样寻找解决方案!

:说实话,Android自己本身没有太多Android Gradle的文档。更不会有升级,如何升级,升级有哪些坑,有坑了怎么办?他们都不会说,他们只说我们又出新版了。这个时候遇到问题,不要急,仔细调试。通过-s,--info,--debug把日志打印出来,然后针对给的日志,一个个解决。我也遇到过很多坑,也解决了很多,所以最后就形成了一本书《Android Gradle权威指南》,帮助更多的人避坑。对于调试,还有一个心得,就是自己写调试的代码,把你想要的信息打印出来。比如在build.gradle脚本文件里写Groovy脚本代码,把需要验证的信息Hook出来,因为Groovy是动态语言,我们可以在运行时做很多事情的。


问:我用 jenkins 打包的时候想把生成的 apk 文件保存在以应用当前的版本号为名称新建的目录下,要怎样才能在 shell 里获取到当前版本号呢?

:你想按版本目录分类,存放你的APK包。这是个不错的办法,而且其他人也明白,这个目录里存放的是什么版本,一目了然 。其实很多办法,一个办法就是我在文章里提的批量修改APK名字那一节,在那里可以做同一处理。针对每个渠道都行。直接用Java代码,File Copy就行。这个不是shell,还是Groovy脚本,用Groovy写,或者Java都可以。版本号就一个变量$versionName就可以获取。如果不想对每个渠道生成的文件处理,那么就在打包完之后,使用一个Task的doLast方法进行处理,也可以的。shell里处理其实没有那么方便,版本号问题,就需要你读取你的版本存放文件,或者在Gradle脚本里,或者在文件里,或者在你的计算公式里。如果你想用shell,我更建议你用Python,更方便。我一般是能解决问题,就好,其实你的目的很明确,获取版本号,创建目录,复制文件。在这个目标前提下,可以用你能用的任何方式。解决问题就可以。


(以上内容转自GitChat,版权归GitChat所有,转载请联系GitChat,微信号:GitChat,原文:《飞雪无情:Android Gradle 技巧实践解析》