在Windows上用ant打包安卓apk

最近在研究多渠道自动打包,需要用到ant,做个笔记,方便以后看。

粗略整理一下看过的一些实用的贴:

1.自动生成build.xml,并实现工程依赖(已实践):

http://www.lephones.net/2014/10/13/ant-apk-with-lib/

这个是博主关于ant打包的集合帖:

http://www.lephones.net/2014/12/02/android-ant-all/

2.工程引用第三方jar包,ant中添加classpath(已实践):

https://my.oschina.net/yunfound/blog/169288

2.1第三方jar包只用作编译,但是不添加到classes.dex

http://www.lai18.com/content/6776196.html

http://stackoverflow.com/questions/10829815/android-ant-build-how-to-compile-against-a-jar-but-exclude-it-from-classes-de

3.自动批量根据渠道信息生成后缀名不同的jar包,并且manifest中的渠道名也不同(已实践):

http://frank-zhu.github.io/android/2014/05/23/android-ant/

4.美团实现一个apk对应所有渠道统计信息的解决方案:

http://tech.meituan.com/mt-apk-packaging.html(美团原贴,思路)

http://www.cnblogs.com/ct2011/p/4152323.html(参照美团思路的具体实现)

5.一个关于ant自动打包过程分析的神贴,不过要在ubantu环境

http://www.cnblogs.com/qianxudetianxia/archive/2012/07/04/2573687.html

6.如何捕获ant构建过程中的异常

http://blog.csdn.net/sxyandapp/article/details/50600910

http://blog.sina.com.cn/s/blog_670bfea20101a81s.html

 

☆☆☆任务一:ant打包应用apk,并且要依赖一些库工程

参考贴:(该贴已实际验证)

http://www.lephones.net/2014/10/13/ant-apk-with-lib/

主要步骤如下: 

1.用ant工具为project生成build.xml文件

用sdk/tools目录下自带的工具,将目录换成我们应用的工程目录,执行下面的命令: 

android update project -p /dir/to/ur/project

就会在目录下生成2个文件,build.xmllocal.properties。

在工程目录新建ant.properties,将下面的配置信息添加到该文件中,记得要修改keystore的路径 

key.store=E:/MyDemo/AndroidDemo/SGSDK_Demo_2/key/sgsdk_key.keystore
key.alias=SGSDK
key.store.password=123456
key.alias.password=123456

这么依赖,在project下执行ant release就可以生成project对应的apk了。

可是如果我们的应用依赖了其他的project怎么办?直接执行ant release会报错,库工程下没有build.xml文件,这种情况,怎么办? 

2.为库工程生成build.xml文件

很简单,为每个库工程都自动生成一个build.xml即可,在eclipse中配置好依赖关系,程序可以运行即可,然后在每个库工程下都执行 

android update project -p /dir/to/ur/project

这样一来,用ant为依赖了库工程的目标工程自动生成apk就实现了。

3.为classpath添加第三方的jar包。

在集成的过程中,发现一个问题,我们目标工程有些jar包是放在runtime目录下的,即不是libs目录下,在eclipse运行的时候,可以通过add to buildpath将这些目录下的jar包添加到编译目录下来避免编译时找不到包,但是用ant编译的时候,却还是报错,import找不到对应的包,什么原因呢?

虽然不知道原因,但是build.xml毕竟是用工具生成的,我也不是特别懂,不晓得到底引用了哪些jar包。

后来搜了下eclipse的add build path,看到http://blog.csdn.net/waeceo/article/details/50484001上说eclipse的add build path只能在eclipse中生效

在Windows上用ant打包安卓apk

后来看到这个帖子https://my.oschina.net/yunfound/blog/169288,结合上一个帖子,我的理解如下:

默认的classpath只包括libs目录下,在eclipse中对一些libs目录下的jar包使用add to buildpath,这个配置只在eclipse中生效,用工具对project生成的build.xml文件中并不会自动生成这部分内容。所以我们要自己修改build.xml文件,将libs目录外的jar包也包含进去(google搜索关键字:安卓 ant 第三方jar)。

解决办法:

https://my.oschina.net/yunfound/blog/169288这个帖子说的很清楚了,直接进去看,so easy

4.给classpath增加了第三方库的路径之后,还是在编译的时候报找不到包的错误??

检查了一下classpath的路径,发现问题了,首先是发现我添加的jar路径错误了,定位到sdk路径下,而不是工程目录下。

在Windows上用ant打包安卓apk
终于发现问题了
在Windows上用ant打包安卓apk
 
在Windows上用ant打包安卓apk
在custom_rules.xml文件中,工程目录下第三方jar包的路径名定义成了 sdk.dir ,而sdk.dir这个值是对应安卓sdk的路径。产生冲突,好吧,把这个sdk.dir sdk.lib改掉去就好。

所以,以后自己的custom_rules.xml文件中定义的变量,一定要避免和系统变量名冲突。否则就会这样张冠李戴。

5.运行非当前目录下的build.xml

ant在dos下默认运行当前目录下的build.xml文件,如果要指定xml文件,使用-buildfile选项,例如:

"ant -buildfile E:\ant\build.xml deploy"

6.eclipse直接run一切正常,但是自动打包的程序就会闪退,而且没有任何提示

如题,就遇到了这种问题,而且没有任何提示。怎么办呢?首先,我想到是不是证书问题,于是我用eclipse导出了正式的apk,也能正常工作,这样一来基本判断是我自动打包工具的问题了。

我对比了一下自动打包生成的apk和eclipse导出的apk里面的结构,发现classes.dex文件大小不同,现在有两个工作需要做:

1.尝试替换classes.dex重新生成apk,看看是否可以正常工作

2.找到出错的那个apk的classes.dex和正常的有哪些区别,找到自动打包出错的地方。

[1]尝试替换chasses.dex并重新打包

[2]对比classes.dex

于是进去查原因,可是文件是二进制的,怎么办?

找到反编译工具,使用 d2j-dex2jar.bat classes.dex 就可以将dex文件反编译出jar包啦,这样就可以逐个对比到底有什么区别啦

7.上面那个问题,发现我用ant生成的apk中的classes.dex,比eclipse导出的要多了两个文件夹,而这两个文件夹正好是runtime目录下两个jar包的内容。明白了,runtime目录下的两个jar包只用于编译,但是并不打包进classes.dex,这该怎么做到呢?

原来是这样的,问题4的时候,我把runtime目录下的两个jar包加入到了project.all.jars.path中,但是这个目录里的jar即参加compile,也参加dex(功能相当于放到libs目录下);而如果有些jar包,只参与编译,不参与打包,加到tested.project.classpath即可(相当于加到了安卓Library)


在Windows上用ant打包安卓apk
 

参考贴:

http://www.lai18.com/content/6776196.html (里面搜索:不参与项目打包)

http://stackoverflow.com/questions/10829815/android-ant-build-how-to-compile-against-a-jar-but-exclude-it-from-classes-de(我是通过搜索project.all.jars.path和tested.project.classpath找到的帖子)

8.同一份代码,在eclipse里没有编译错误,但是ant release却报编译错误,类型转换失败?

在Windows上用ant打包安卓apk

后来找到原因了,是JDK版本不一致导致的,我在eclipse工程里JDK版本是1.7,就不会有这个报错,而如果改成1.6在eclipse中也会有这个报错。

怎么修改ant时候的jdk版本呢?

修改local.properties文件,加上这两行即可

java.target=1.7

java.source=1.7

!!!解决

!!!!!尚未解决的问题

现在有个问题,加入依赖库里有个jar包叫umeng.jar,我的工程引用了依赖库,但是本目录下没有umeng.jar

用eclipse运行就么有错误,但是用ant就会报编译错误

是不是一样的原理???

☆☆☆目标二:批量自动多渠道打包

参考贴:(已验证,可以生成带渠道名后缀的apk文件)

http://frank-zhu.github.io/android/2014/05/23/android-ant/

按照文章中描述的,已经可以在本地运行,但是中间出现过一些bug,列举如下:

1.报一个编码的错误,后面没能重现

解决方法在网上找一下就有,挺容易解决的

把自己的的build.xml中的encoding全部改成encoding="UTF8"即可

2.报错 <javac 不支持的编码 utf-8 

我看上说是编译文件时默认为的事java.encoding的编码方式,一般是GBK,所以会报错

倒腾了好久,改了下android-sdk/tools/ant/build.xml

<javac encoding="${java.encoding}" 
改成
<javac encoding="utf-8"

虽然在自己的ant.properties文件里配了java.encoding="utf-8"可不知道为什么没生效,改了之后就好了 

!!!不过现在居然又不能重现了!!!

3.报错: key 加载失败之类的错误

注意ant.properties里跟key、密码相关的配置项后面不可以有空格

4.下面这种情况需要clean一下工程 

在Windows上用ant打包安卓apk
 

5.引用了库工程,但是在工程目录下找不到build.xml,报错

在Windows上用ant打包安卓apk
 就是因为这个问题,所以才会找到帖子一。

目标三:如何捕获ant构建过程中的异常呢

参考贴:

http://blog.csdn.net/sxyandapp/article/details/50600910

http://blog.sina.com.cn/s/blog_670bfea20101a81s.html

结合参考的帖子,自己的demo

<?xml version="1.0" encoding="UTF-8"?>
<project default="release" name="custom_rules">
	<taskdef resource="net/sf/antcontrib/antcontrib.properties">
		<classpath>
			<pathelement location="D:/software/ant/apache-ant-1.9.7/lib/ant-contrib-1.0b3.jar"/>
		</classpath>
	</taskdef>
	<target name="deploy">
		<trycatch>
			<try>
				<antcall target="clean"/>
				<antcall target="release"/>
				<copy tofile="./output/${output.apk.name}.apk">
					<fileset dir="${out.absolute.dir}/" includes="${ant.project.name}-release.apk"/>
				</copy>
				<delete includeEmptyDirs="true">
					<fileset dir="${out.absolute.dir}" includes="**/*"/>
				</delete>
			</try>
			<catch>
				<echo message="result" file="E:/ant_result.txt" />
				<echo level="error">构建错误,按Enter结束</echo>
				<input />
			</catch>
		</trycatch>
	</target>

</project>

 

还会继续完善

相关推荐