专栏首页腾讯移动品质中心TMQ的专栏从 Ant 到 Gradle 的迁移之路
原创

从 Ant 到 Gradle 的迁移之路

作者:李金涛

团队:腾讯移动品质中心TMQ

笔者语:Gradle是一个类似于Ant和Maven的自动化构建工具,是Android App天然的构建工具。

本文总结了项目从Ant迁移到Gradle的实践经验和相关技巧,供大家参考。

由于Gradle的种种优点(大家可以参考网上的资料,这里不多说了),前一段时间项目组打算将原来的Ant编译打包方式迁移到Gradle编译打包方式。现在迁移基本完成,我这里将迁移过程遇到的坑以及经验做一个总结,希望能给大家在Ant转Gradle的时候带来一些提示。

一、Ant打包流程

这里,我们先来看一下Ant脚本的一个片段:

这段脚本执行的流程是:

上述编译打包关键任务的说明:

(1)compile:编译工程代码;

(2)genMainDexFilelist:生成主dex的类列表;

(3)genSecondDexFilelist:生成从dex的类列表;

(4)package_res_with_assets:打包资源文件;

(5)package:将代码和资源一起打包成apk。

从Ant脚本和流程可以看出,Ant的任务都是直接在脚本中实现,然后按照脚本定义的执行顺序来依次执行任务。

二、Gradle打包流程

这里先给出一个Gradle脚本的最简单的模版,如下:

这个最简单模版即可完成apk的编译、打包、签名等过程。它是怎么做到的呢?

原来,在Gradle中,官方已经为我们定义好了一个专门编译打包App的Gradle插件,该插件包含了Apk编译打包的基本任务,我们就不用自己再费力去重写了,可以直接复用。这个添加的插件就是上面Gradle脚本的第一行:

apply plugin: 'com.android.application'

在该插件中,默认的编译打包流程如下:

上述编译打包关键任务的说明:

(1)compileReleaseJavaWithJavac、compileReleaseSources:主要完成了Java代码的编译,生成class文件。

(2)transformClassesAndResourcesWithProguardForRelease:主要完成了Java代码的混淆,生成混淆后的jar包和mapping文件。

(3)transformClassesWithDexForRelease:主要完成了将class文件和第三方库一起打包生成Dex字节码文件。

(4)packageRelease:主要完成了将Dex字节码文件和其他资源文件一起打包。

在这个插件中,代码编译、打包等基本任务已经有了,但是我们还有一部分自定义的任务怎么办呢?只能从Ant移植过去!

因为打包方式从Ant移植到Gradle后,最重要的是保证打包的功能和最终效果保持不变,做到平滑的移植。所以,这里我们就应该平滑的将Ant任务改造成Gradle任务,然后移植到Gradle脚本中。

这里Gradle跟Ant有一个很明显的区别就是,Ant的任务基本上都是自定义的,代码直接可见,所以我们想要添加、插入、删除任务都比较方便。但是Gradle的基本任务都在插件中,代码不可见,那么我们自定义任务以后该怎么跟插件的任务融合在一起呢?

接下来我们具体说明。

三、Ant任务改造成Gradle任务

下面就以dex分包过程中生成从dex的类列表为例,来说明如何将Ant中自定义的任务移植到Gradle。

Ant任务代码示例:

这是一个shell脚本任务,目的是分包时生成从dex的类列表。

将Ant任务改造成Gradle任务时,为了平滑改造以及减少改造的工作量,我们仍然采用这个shell脚本。由于Gradle的方式也可以直接调用shell脚本,所以我们的Gradle任务定义如下:

以上两种方式均可达到同样的效果。

上述代码中的main_dex_filelist、tempDir、binDir是该task中用到的自定义局部变量,它们可以跟单独的task就近定义,也可以多个任务一起集中定义。

任务定义好了,放在Gradle脚本的什么位置呢?直接放在脚本文件后面就好,跟android定义块分开。具体例子如下:

四、自定义Gradle任务的注入

Gradle的任务定义好以后,我们还需要将它加入到Gradle的编译打包流程中才可以被执行。

正如前面所说,由于Gradle的App编译打包插件已经有一个基本的、完整的流程,我们自定义的任务必须插入到这个流程中合适的位置,这一步也称作任务的注入。

任务注入的方法是利用Gradle任务之间的依赖关系。

比如,我们这个任务genSecondDexFilelist需要放在代码编译之后、apk打包之前,怎么做呢?可以放在afterEvaluate块中注入。具体代码如下:

下面对这段代码进行解释:

(1)afterEvaluate说明是在Gradle脚本解析完之后、task开始执行之前插入任务;

(2)第一个dependsOn是使“genSecondDexFilelist”任务依赖于“transformClassesAndResourcesWithProguardForRelease”所有的依赖;第二个dependsOn是使“transformClassesAndResourcesWithProguardForRelease”依赖于“genSecondDexFilelist”。这样一来,就将“genSecondDexFilelist”置于“transformClassesAndResourcesWithProguardForRelease”之前了。

在完成genSecondDexFilelist任务的注入以后,我们的Gradle脚本变成如下的样子:

这样,一个Ant任务就改造成Gradle任务并注入完成了。

其他的Ant任务可以同样移植过来。

五、任务移植实例

1、dex分包

Gradle自带dex分包插件,但是缺点是定制比较麻烦。我们在Ant下已经有现成的自己定制的dex分包脚本和相关配置,如果能直接在Gradle中使用,那就好了。怎么做呢?

根据上面自定义任务和插入任务的做法,我们只需将Ant下已有的分包任务改写成Gradle任务,已有的shell脚本照搬过来,然后再把任务注入到Gradle插件的编译打包流程中即可。

前面已经演示了如何把生成从dex类列表的任务改造、注入Gradle任务流程中,其他任务可用类似的方法来实现移植。

2、代码混淆

代码混淆在我们的移植过程中也是一个坑。

Gradle也自带代码混淆插件,但是它默认的混淆跟我们Ant下混淆出来的结果很不相同。要想让Gradle下的混淆跟我们Ant下的混淆完全一样,则需要重写混淆配置文件和调试,这个过程比较麻烦。如果能把我们在Ant下已有的混淆配置拿过来直接用,那肯定是最好的。怎么做呢?方法就是弃用Gradle自带的混淆任务,使用我们自定义的混淆任务。

弃用Gradle混淆任务的方法是在Gradle脚本的buildTypes中设置minifyEnabled为false,然后自定义混淆任务并注入到编译打包流程的适当位置。

自定义混淆任务时,混淆的配置可以放在一个配置文件中,然后在任务中引用;也可以直接放在任务体的代码中。这两种形式体现在代码上有所不同,具体举例如下:

第一种形式:混淆配置放在配置文件中

第二种形式:混淆配置直接放在任务体中

这两种形式本质上是一样的,但是它们还是有些使用上的不同:

第一种形式的优点是Proguard的配置都放在一个独立的配置文件中,可以减少Gradle脚本的代码量,代码看起来更清爽。不过,它有一个缺点就是不好传入和使用Gradle脚本中定义的通用变量,这在某些情况下可能不太方便(比如,Proguard使用的jar包路径可能包含编译时的环境变量,我们就无法在配置文件中使用该环境变量)。

第二种形式的优缺点正好跟第一种形式相反。

我们在使用的时候可以根据情况来选择使用哪种形式。

六、总结

以上讲述了我们从Ant到Gradle的移植方法和案例。无论是Ant脚本还是Gradle脚本,其中关键的地方还是在于如何定义任务、如何让任务做正确的事,这才是真正考验我们代码能力的地方。

欢迎大家一起讨论交流!

获取更多测试干货,请搜索微信公众号:腾讯移动品质中心TMQ!

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 结合静态代码扫描来给插件间接口把把脉

    如火如荼的EP建设中小鹅收到了一个小小的需求,如何知道每个版本变更了哪些插件间接口呢,有没有及时覆盖?

    腾讯移动品质中心TMQ
  • 从wireshark抓包开始学习https

    导语 目前互联网大量web的应用层协议从http迁移到了https,https已经在越来越多的场合替换http协议。近期由于业务需要,我们通过Wireshark...

    腾讯移动品质中心TMQ
  • 快速探索,音视频技术不再神秘

    ? 一、采集 - 数据从哪里来? 1.1 采样原理 定义:对连续变化图像在空间坐标上做离散化处理,将模拟信号转变成数字信号的过程,即为图像进行采样。 通俗...

    腾讯移动品质中心TMQ
  • Gradle 概述

    Gradle 是一个开源的构建自动化(build automation)工具。有关构建自动化的定义请参考:https://en.wikipedia.org/wi...

    HoneyMoose
  • Gradle和Maven性能对比

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    乐百川
  • MAC上使用Android Studio 3.0的Gradle问题小解

    2017-06-11 by Liuqingwen | Tags: Android Gradle | Hits

    IT自学不成才
  • 看似无用,实则重要的Gradle Wrapper

    在本系列的此前文章中,我们学习了为什么要用Gradle、Gradle的入门基础和Groovy的基础,这些文章为Gradle的入门打下了基础,这一篇我们接着学习G...

    用户1269200
  • Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车

    接上一篇 Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业...

    newbe36524
  • Gardle 是什么

    Gradle 只运行那些输入和输出有改变的任务,从而避免无效的工作。另外,还可以通过缓存开关重用之前的任务输出(其他的机器上的缓存也是可以的)。 Gradle还...

    佛系编码
  • 使用Gradle管理你的Android Studio工程

    关于Android Gradle更多详细内容已经出书《Android Gradle权威指南》,大家可以购买,看更多没有介绍的知识点和内容,购买链接如下

    飞雪无情

扫码关注云+社区

领取腾讯云代金券