前提,本文的要求是你要懂一些 ant
在 Android 的sdk 中有一个已经写好的 build.sh, 通常情况下在各个 apk 中都是创建一个 build.xml,在里面会引用或者重载这个 build.xml 中的部分字段,而不是自己完全开始重头写一个新的。sdk 这个 build.xml 位置 “android-sdk-windows\tools\ant\build.xml”
如果你自己的工程目录中没有 build.xml ,那么可以通过命令
android update project -p .来产生一个,如果不能创建,说没有指定什么 target 那么需要在创建一个 project.properties,然后在里面指定 target,例如:
target=android-14
执行成功后通常会创建出来两个文件:local.properties,build.xml
好了,下面开始解决实际问题:
问题一: 如何给 Apk 加上版本号,例如:abc_1.1.apk 这样的形式
在自己的 app 的工程中增加一个新的文件 "custom_rules.xml" 为什么是这个文件呢? 因为在你 build.xml 中有如下文字
<import file="custom_rules.xml" optional="true" />来指定可以导入的第三方文件,名字叫做 custom_rules.xml,好了,这个 xml 的内容如下
<?xml version="1.0" encoding="UTF-8"?> <project> <target name="rename-release-with-version-number"> <xmlproperty file="AndroidManifest.xml" prefix="themanifest" collapseAttributes="true" /> <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-${themanifest.manifest.android:versionName}.apk" /> </target> <target name="-set-release-mode" depends="rename-release-with-version-number,android_rules.-set-release-mode"> <echo message="target: ${build.target}"></echo> </target> </project>简单来说就是,
1. 写一个 target 解析 AndroidManifest.xml 得到 version name 和 version code 这两个属性,然后重载 "out.final.file" 字段将其设为这新的名字
2. 然后将这个 target 放到 "-set-release-mode" 的 depends 中这样保证调用 "-set-release-mode" 的时候就会调用这个写好的 target
说明:
"-set-release-mode" 这的实在 sdk 的 build.xml 中有定义的,每次使用 ant release 的时候都会执行这个字段
“out.final.file”在 sdk 的 build.xml 中的定义如下
<property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-release.apk" />我们就是要重载它。
“android_rules.-set-release-mode” 这个指的就是要执行 sdk build.xml中原本 "-set-release-mode" 所定义的 depends
另外在 sdk 的 build.xml 中本来就定义好了两个 property 叫做,
<property name="version.code" value="" /> <property name="version.name" value="" />
好了,将这个 custom_rules.xml 放到你的工作中,然后在 AndroidManifest.xml 中设置好 version code 和 version name,然后执行 ant clean 就可以在 bin 目录下看到新的 apk,并且是 abc-1.0.1.apk 这样的形式。
问题二:如何在 jar 的 build 过程中将版本信息从 AndroidManifest.xml 中保存到 MANIFEST.MF 中
需求,将代码打包成一个 jar 包,但是通常 jar 包中不会将 AndroidManifest.xml 打包进去,并且通常 jar 的版本都放到 MANIFEST.MF 中,并且也有专门的代码去解析它。
解决方法:
创建 custom_rules.xml,内容如下
<?xml version="1.0" encoding="UTF-8"?> <project> <!-- Override the default compile process --> <target name="-compile" depends="android_rules.-compile"> <!-- Parse AndroidManifest.xml since ${version.code} and ${version.name} is empty --> <xmlproperty file="AndroidManifest.xml" prefix="themanifest" collapseAttributes="true" /> <jar destfile="${out.library.jar.file}"> <!-- Override manifest.mf add code version --> <manifest> <section name="custom_section"> <attribute name="verion_name" value="${themanifest.manifest.android:versionName}" /> <attribute name="verion_code" value="${themanifest.manifest.android:versionCode}" /> </section> </manifest> <!-- Copy code from android sdk build.xml to create jar --> <fileset dir="${out.classes.absolute.dir}" includes="**/*.class" excludes="${manifest.package.path}/R.class ${manifest.package.path}/R$*.class ${manifest.package.path}/Manifest.class ${manifest.package.path}/Manifest$*.class ${manifest.package.path}/BuildConfig.class"/> <fileset dir="${source.absolute.dir}" excludes="**/*.java ${android.package.excludes}" /> </jar> </target> </project>重载 “compile” target,在生成 jar 的地方完全用这块代码来替换
<manifest> 的那块代码就是要放到 MF文件中的内容,<section name="custom_section"> 这个表示是在 MF 文件中创建一个自己的 section,这个可有可无,下面的
<fileset dir="${out.classes.absolute.dir}" 直接从 sdk build.xml 中拷贝过来没有改变。
好了,执行完 ant 命令之后再 MANIFEST.MF 中就可以看到来自 AndroidManifest.xml 中的版本信息了。