Android ant 自动打包(多渠道)
--Zhouxueliang
前段时间项目需求,研究了下ant,简单总结下,趁感冒copy上来....
当一个代码项目大了以后,每次重新编译,打包,测试等都会变得非常复杂而且重复,因此c语言中有make脚本来帮助这些工作的批量完成。在Java 中应用是平台无关性的,当然不会用平台相关的make脚本来完成这些批处理任务了,ANT本身就是这样一个流程脚本引擎,用于自动化调用程序完成项目的编译,打包,测试等。
当然,ant比ide更迅速快捷,更加效率。
环境搭建
Ant需要用到一些环境变量,包括android的,java的,ant的,需要在系统环境变量里创建他们:
ANDROID_HOME: android sdk的根路径
JAVA_HOME: jdk 根路径
ANT_HOME: ant 根路径
ant 官网可下载
ant 环境配置:
1。解压ant的包到本地目录。
2。在环境变量中设置ANT_HOME,值为你的安装目录。
3。把%ANT_HOME%/bin加到你系统环境的path。
4。执行ant测试安装,敲下ant回车下就知道了
ant试打包
这里我们要知道一些Android命令。
前提条件已配置好android sdk 环境,所以可以在任意目录下执行android 命令,不然则要切换到 android-sdk\tools目录下
创建一个android项目
android create project -k com.?????.appmarket nk -a appmarket -t 6 -p /work/AppMarket
-k /--package 为命名空间(包名)-a /--name 工程名 -p /--path 项目 -t 为目标平台的版本编号 可以通过“android.bat list targets ”获取
对已经存在的android工程,我们可以update下(修改平台的版本),这样会自动添加build.xml 等ant 的配置文件
android update project --name com.?????.appmarket -t 6 -p /work/AppMarket
--name 程序名 –t为目标平台的版本编号 –p 工程路径
update以后得到工程相应的build.xml,我们需要的重要文件之一
在工程目录下执行ant,ant会执行当前路径下的build.xml的配置文件,build.xml里面定义了很多target,每一个target相当于一个目标任务,执行ant时列出的相关的可执行任务,如release,debug,clean……
顾名思义,执行ant release 就是创建release包的意思(未带签名信息)
到这一步,ant自动打包的基础功能就差不多了
apk签名
编辑build.xml,我们可以发现这个文件极小,几十行的样子,而且大部分都是注释,其实主要工作都是定义在${ANDROID_HOME}/tools/ant/build.xml这个文件里面,几乎包括所有target任务。而我们工程里面的build文件只是引用了这个文件而已。
在负责apk签名的target:-release-sign里,用到了一下几个变量:
key.store(签名文件:文件路径+文件名)
key.store.password(签名文件密码:密码)
key.alias.password(签名文件密码:密码)
key.alias(签名文件别名:??????)
当然,我们没有定义过这几个变量,也没有赋值,他们是空的。一般的做法是我们可以定义到一个文件里(这里一般用XXX.properties),然后加载到build文件里面:
<property file="XXX.properties" />
但是这里遇到了点问题,我们的签名文件的别名是“???有限公司”,中文的,导致读取这个值的时候直接错误:迅雷网络技术有限公司 没有找到……
换一下编码"????有限公司"(网上很多这种编码工具的)
但是写到.properties里面依然提示:"??????有限公司" not found...
好吧,这里可以直接写到build.xml里解决,直接加载build文件前面。
好的,执行ant release通过,创建第一个release签名包没问题了,在bin下
最后可以执行ant clean清理掉。
多渠道包支持(原理)
我们的目标是打N个包,简单是思路是循环改变channels id 重复打包,难点有2,改变ids,循环打包。
实现批量循环打包需要一个类似于for循环的功能,在Ant的核心包里没有相关的For循环的Task,即不支持for循环,但是ant支持第三方扩展包,以支持更多的其他功能。于是我们要下载相应的支持for循环的扩展包。可以使用开源的Ant-contrib包。下载地址:http://ant-contrib.sourceforge.net/。下载后的解压得到的jar文件放到ant的lib目录。
Ant加载第三房任务扩展:
taskdef resource="net/sf/antcontrib/antcontrib.properties"> <classpath> <pathelement location="lib/ant-contrib-1.0b3.jar"/> </classpath> </taskdef>
这样我们就可以可以使用扩展的<foreach>< /foreach >
<target name="channels"> <foreach target="XXXXX" > </foreach> </target>
然后在android工程里面定义一个channel Id的变量(定义在res/values/package.config里面),从文件ids读入channels,依次替换channelId循环打包
实现:(ant不支持中文哦)
<!—定义一个打渠道包的target -->
<target name="deploy">
<!—定义输入目录 -->
<mkdir dir="out"/>
<!—从渠道包信息文件中读入ids -->
<loadfile property="market_channel" srcFile="./ids.txt" />
<echo>${market_channel}</echo>
<!—渠道包信息传给target="modify_config",循环-->
<foreach target="modify_config" list="${market_channel}" param="channel" delimiter=",">
</foreach>
</target>
<!—modify_config 负责修改渠道包id并调用release 打包 -->
<target name="modify_config">
<!—定义渠道名和渠道id,字符串操作,截取相应字段-->
<propertyregex property="cname" input="${channel}" regexp="(.*):" select="\1"/>
<propertyregex property="cid" input="${channel}" regexp=":(.*)" select="\1"/>
<!—修改渠道名和渠道id -->
<replaceregexp file="res\values\package_config.xml"
flags="g"
byline="true">
<regexp pattern="name="channelName"\>(.*)</string" />
<substitution expression="name="channelName"\>${cname}</string" />
</replaceregexp>
<replaceregexp file="res\values\package_config.xml"
flags="g"
byline="true">
<regexp pattern="name="channelId"\>(.*)</string" />
<substitution expression="name="channelId"\>${cid}</string" />
</replaceregexp>
<!—打包 -->
<antcall target="release" />
<!—输出 -->
<copy tofile="out/${ant.project.name}-${cname}.apk" file="bin/${ant.project.name}-release.apk"/>
</target>
操作
说得那么多,实际操作是:
1. 配置环境(android,java,ant)
2. 把相应文件拷到工程下(build,ids,keystone)
3. 在工程目录下执行ant deploy
然后耐心等结果。(appmarket 17个包,用时9分32秒,还是很快的)
注:此方法在mac,windows 7 x64运行通过,其他版本请酌情测试,此文所有展示文件是window 7 x64下生成。
其他详情
这是渠道信息文件格式,读入的时候以“,”分割成list,然后以“:”分割成渠道名和渠道id。
第一次发博,技术有限,请笑纳,不客气,呵呵