用 Ant 编译 Android 工程及定制的方法

  通常开发和编译 Android 程序都在 Eclipse 里完成,但是这样不太方便对工程做持续集成,而且也不方便对编译过程做些自定义的控制。当然可以在了解 Android 程序完整的编译、打包和签名过程后全部自己用 script 搞定,但更好的方法是用类似 Ant 或者 Maven 这类编译工具来做,Android 对 Ant 支持的不错,官方文档可以参考“Managing Projects from the Command Line”和“Building and Running from the Command Line”。另外还有这篇“Using Ant to Automate Building Android Applications”也非常值得一看,不过由于 Android SDK 的持续更新,里面有些内容已经不再适用,下面就 share 一下我用 Ant 编译 Android 工程的一些过程和心得。

  我的工程使用了 ActionBarSherlockViewPagerTabs(和工程文件夹位于同级目录中。鉴于这两个库实现的效果和质量,他们被使用在同一个工程中的几率还是很高的),已经可以在 Eclipse 里正常编译和运行,为了用 Ant 编译,首先要产生 build.xml 文件,但是在这之前还要做一件事。ViewPagerTabs 引用了 Support Package,而 ActionBarSherlock 自己内含了一份 Support Package 的源码,用 Eclipse 是可以顺利编译的,但是如果不做任何处理的话,用 Ant 编译时就会遇到某 class 已经存在之类的问题。

  首先需要删除位于 ViewPagerTabs 的 libs 目录下的 android-support-v4.jar,然后让 ViewPagerTabs 引用 ActionBarSherlock 即可,看起来简单,但是这个问题让我这个从没用过 Ant 的菜鸟折腾了一天才搞定,惭愧惭愧。

  生成 build.xml 的步骤如下:

  • 进入 ActionBarSherlock 文件夹,执行 android update lib-project –path .
  • 进入 ViewPagerTabs 文件夹,执行 android update lib-project –path .
  • 进入工程主文件夹,执行 android update project –path .

  由于先期已经在 Eclipse 里面做了编译,所以主工程目录中的 project.properties 里已经添加过了对其它库的引用,所以为主工程生成 build.xml 时不需要再加 –package 来添加引用库的位置了。上述命令执行以后,工程目录里多了两个文件:build.xml 和 local.properties。前者对于刚刚接触 Ant 的人来说,信息量比较大,而 local.properties 里面只是简单的记录了 Android SDK 的位置,而且由于这个文件是工具自动生成的,所以不要把它 check in 到版本控制系统里去。

  接下来到主工程所在目录执行 ant debug 或者 ant release 就可以顺利编译了。

  接下来看看定制 build.xml,上面提到的那篇“Using Ant to Automate Building Android Applications”里面提到的方法其实太过复杂,我们不用把系统 build.xml 里面的内容都复制到本地 build.xml,而是只需要在本地 build.xml 里增加一个 pre-compile 就可以了,增加的内容如下:

  1. <property file="build.properties" />
  2.  <target name="-pre-compile">
  3.      <copy file="config/Config.java" todir="${source.dir}/com/2ndboy/App" overwrite="true" encoding="utf-8">
  4.          <filterset>
  5.              <filter token="CONFIG.FOO" value="${config.foo}"/>
  6.          </filterset>
  7.      </copy>
  8.  </target>

在主工程目录下新建一个名为 config 的目录,里面有个名为 Config.java 的文件,内容如下:

  1. public class Config
  2.  {
  3.      public final static boolean freeVersion = @CONFIG.FOO@;
  4.  }

这个 Java 源文件里的 CONFIG.FOO 会被 build.xml 里的新增部分在编译期间用 ${config.foo} 的内容替换掉,而 ${config.foo} 的定义在 build.properties 里面:

  1. config.foo=false

Ant 的深入使用又牵扯到一大堆东西,这里只是浅尝辄止而已,学无止境!

Leave a Reply