计划写个完整的使用Ant打包Android应用的系列文章,三篇文章。首篇详细介绍采用Ant打包Android应用的流程,列出部分定制问题及其解决方法,第二篇介绍我理解的Ant打包的思路与基本的概念和使用,最后一篇描述apk包的生成过程。
android update project --name 自己起的工程名 -p .
在工程目录下就会生成Ant编译需要的build.xml,直接运行ant debug,即可完成编译,并在bin目录下生成debug版本的apk包。需要注意的几个问题是:
[aapt] invalid resource directory name: 工程目录/bin/res crunch
BUILD FAILED
sdk/tools/ant/build.xml:649: The following error occurred while executing this line:
build.xml:694:null returned: 1
一般看到res crunch,应该就是你在eclipse中工程自动编译的文件与ant生成文件冲突,只要关掉eclipse的自动编译,clean下工程重新跑ant即可。
(3)可以留心看下project.properties和local.properties
2.添加代码混淆
在工程的project.properties文件中有注释说明如何打开代码混淆
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
去除#号即可,同时可以在proguard-project.txt增加你需要特殊处理的配置
修改后,再执行ant release,你会在输出中看到
-obfuscate:
[mkdir] Created dir:工程目录/bin/proguard
[jar] Building jar: 工程目录/bin/proguard/original.jar
[proguard] ProGuard, version 5.2.1
...
可以看到我用的proguard版本,但是用ant debug是没有proguard,因为只有release版本才需要混淆,具体原因后续文章会详细讲述。混淆后的mapping文件在bin目录下。
注意的问题:工程的AndroidManifest.xml中如果配置了android:debuggable=true,那么即使ant release也不会混淆代码
3.签名
首先给apk签名需要keystore,具体的生成此处不细讲,简单的说在eclipse中选则工程,右键android tools -> export android application 中有生成选项
其次是在工程目录下新建ant.properties文件,里面配置你的签名信息
例如:
key.store=kestore文件的路径
key.store.password=密码
key.alias.password=密码
key.alias=别名
此时再执行ant release,在bin目录下可生成“工程名-release.apk”,你最终要的release版本的apk
到此,简单android工程的的ant编译打包完成,非常方便。
二、添加定制化
1.加入so库
Android应用的Ant编译默认是不会编译jni工程的,它只会处理libs中的库文件。如果你的libs中刚好有编译好的so,那打包好的apk似乎能正常运行。在配置好的jni工程,只要运行ndk的ndk-build即可完成so的编译。因此,只要在build.xml同目录中添加custom_rules.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project name="工程名" default="help">
<target name="-pre-compile">
<echo >ndk build.............................</echo>
<exec executable="${ndk.dir}/ndk-build" >
</exec>
</target>
</project>
在同目录下的local.properties中增加一行,指定你的ndk目录
ndk.dir=ndk路径
再次执行ant release,查看你的so库是否已生成
如果你的jni工程是作为库工程存在,方法是一样的。主工程依赖你的库工程,在库工程中也生成build.xml,然后按照上面的方法操作即可。
2.调用隐藏api,加入android.jar
不少工程是基于Android原生代码修改而来,或者就是想调用系统隐藏的部分api,就会用到别人编译好的android.jar,或者framework.jar等其它什么名字的库文件,而且会要求加载的顺序在你选择的android编译版本之前。在eclipse的Java Build Path->Libraries中调整其加载顺序,那么ant编译怎么修改呢?还是利用前面编写的custom_rules.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project name="hooktest" default="help">
<property name="project.target.android.jar" value="${sdk.dir}/platforms/${target}/android.jar" />
<target name="-pre-compile">
<echo >set project target class path.............................</echo>
<path id="project.target.class.path">
<pathelement location="framework.jar"/>
<pathelement location="${project.target.android.jar}"/>
</path>
<property name="my.project.target.class.path" refid="project.target.class.path" />
<echo message="project.target.class.path:${my.project.target.class.path}" />
</target>
</project>
3.一个工程中多源码目录
如果一个工程中设置了多个源码目录,不太合适的方法就是先拷贝其它的源码目录到默认的src下,在编译完成后再删除。其实顺便看看文件拷贝和删除,在多源码目录的工程中也建立custom_rules.xml,主要内容如下:
<target name="-pre-build">
<echo >copy file.............................</echo>
<copy todir="${source.absolute.dir}">
<fileset dir="其它源码目录">
<include name="**/*.java" />
<include name="**/*.aidl" />
</fileset>
</copy>
</target>
<target name="src-clean" >
<echo >delete file.............................</echo>
<delete dir="${source.absolute.dir}/拷贝的源码目录" />
</target>
<target name="-post-build" depends="src-clean">
</target>
<target name="-pre-clean" depends="src-clean">
</target>
上述代码在执行ant clean时也会执行删除拷贝的源码操作,而在编译前先拷贝源码,包括aidl文件,之后在打包完成后删除拷贝的源码目录。
一个工程中的源码尽量就弄在一个目录里吧。其它问题还有如库工程间的资源引用,如果直接使用默认的R文件是没有问题的,但是要是在eclipse中利用build Java Build Path->project添加了子工程,并且还用了其中的R文件来应用资源,那么ant打包就还得再继续折腾
结尾:
这里仅给出了使用Ant打包Android应用的基本过程和可能问题的解决方法,至于ant的使用和打包原理既可以看参考文章,也可以看后续的补充文章。
参考:
1.android命令详细说明http://developer.android.com/tools/help/android.html
3.ant打包apk详细的过程可阅读sdk/tools/ant/build.xml文件