就我而言,我只是想在不同版本之间更改strings.xml 中的一些值。
首先我必须加载ant-contrib 库,以定义for 循环任务:
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib-1.0b5-SNAPSHOT.jar" />
</classpath>
</taskdef>
我将我的配置列表config.names 放在properties 文件中:
config.url.root=http://projectserver.aptivate.org/
config.names=student-production, teacher-production, student-testing, teacher-testing
并定义一个build-all 目标,该目标在config.names 上循环:
<target name="build-all">
<for param="config.name" trim="true" list="${config.names}">
<sequential>
为每一个定义一个自定义的resources目录,将目录名称保存在config.resources属性中:
<var name="config.resources" unset="true" />
<property name="config.resources" value="bin/res-generated/@{config.name}" />
删除它,将res的全局资源复制到其中:
<delete dir="${config.resources}" />
<copy todir="${config.resources}">
<fileset dir="res"/>
</copy>
将配置名称中的 - 更改为 /,使其成为 URL 参数中的路径:
<var name="config.path" unset="true" />
<propertyregex property="config.path"
input="@{config.name}" regexp="-"
replace="/" casesensitive="true" />
运行 XSLT 转换以修改 strings.xml 文件:
<xslt in="res/values/strings.xml"
out="${config.resources}/values/strings.xml"
style="ant/create_xml_configs.xslt"
force="true">
<param name="config.url.root" expression="${config.url.root}" />
<param name="config.name" expression="@{config.name}" />
<param name="config.path" expression="${config.path}" />
</xslt>
这是我使用的 XSLT 样式表:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="config.url.root" />
<xsl:param name="config.name" />
<xsl:param name="config.path" />
<!-- http://my.safaribooksonline.com/book/xml/9780596527211/creating-output/xslt-id-4.6 -->
<xsl:template match="/">
<!--
This file is automatically generated from res/values/strings.xml
by ant/custom_rules.xml using ant/create_xml_configs.xslt.
Do not modify it by hand; your changes will be overwritten.
-->
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- the value of update_server_url must end with a slash! -->
<xsl:template match="string[@name='update_server_url']/text()">
<xsl:value-of select="$config.url.root" /><xsl:value-of select="$config.path" />/
</xsl:template>
<xsl:template match="string[@name='app_version']/text()">
<xsl:value-of select="." />-<xsl:value-of select="$config.name" />
</xsl:template>
</xsl:stylesheet>
然后回到custom_rules.xml,然后我从原始(未修改)res/values/strings.xml 中提取app_version:
<xpath input="res/values/strings.xml"
expression="/resources/string[@name='app_version']"
output="resources.strings.app_version" />
并使用antcall 任务调用debug 构建:
<antcall target="debug">
<param name="resource.absolute.dir" value="${config.resources}" />
<param name="out.final.file" value="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}-@{config.name}.apk" />
</antcall>
具有两个更改的属性值:
-
resource.absolute.dir 告诉debug 目标使用我修改过的res 目录,在上面的config.resources 属性中定义;
-
out.final.file 告诉它生成一个具有不同名称的 APK,包括配置名称(例如 student-testing)和从 strings.xml 中提取的版本号。
最后,我可以从命令行运行ant build-all 并构建所有四个目标。多一点脚本,就在build-all目标结束之前,将编译好的APK文件一起列出以供参考:
<echo message="Output packages:" />
<for param="config.name" trim="true" list="${config.names}">
<sequential>
<echo message="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}-@{config.name}.apk" />
</sequential>
</for>