实例工程、所需的文件都在最后的附件中。
今天花费了几个小时,参考网上的资料,期间遇到了好几个问题,
终于实现了使用Ant批量多渠道打包,现在,梳理一下思路,总结使用Ant批量多渠道打包的方法:1. 下载安装Ant,不是使用Androis
sdk 或者 Eclipse中的Ant,而是去官网下载完整的Ant。官网:http://ant.apache.org/
1)
解压Ant,比如解压到D:\Android\Ant
2)
我的电脑->属性->高级->环境变量
3)
系统变量新建ANT_HOME,变量值为D:\Android\Ant
4)
系统变量新建或修改path,变量值为%ANT_HOME%\bin
测试ant是否成功,你可以在控制台输入Cmd 回车, ant
回车。如果出现
Buildfile:
build.xml does not exist!
Build
failed
恭喜你已经ant安装完毕了!!
2. 安装扩展包
Ant-contrib,支持循环打包。
1)
到http://sourceforge.net/projects/ant-contrib/files/ant-contrib/ 下载1.0b3
2)
从下载的压缩包中复制ant-contrib-1.0b3.jar,到放到Ant的lib文件夹中。
3.
复制签名key文件“gaoxin.key”到工程的更目录下。
4.
在工程的根目录下创建文件build.xml。
1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- name="time" 替换成你的工程名 --> 3 <project 4 name="time" 5 default="release" basedir="."> 6 7 <!-- ANT环境变量 --> 8 9 <property environment="env" /> 10 <!-- 使用第三方的ant包,使ant支持for循环 --> 11 12 <taskdef resource="net/sf/antcontrib/antcontrib.properties" > 13 14 <classpath> 15 <!-- 替换成你存放ant-contrib-1.0b3.jar的地方。 --> 16 <pathelement location="C:/apache-ant-1.9.4/lib/ant-contrib-1.0b3.jar" /> 17 </classpath> 18 </taskdef> 19 <!-- 应用名称 --> 20 21 <property 22 name="appName" 23 value="${ant.project.name}" /> 24 25 <!-- SDK目录(获取操作系统环境变量ANDROID_SDK_HOME的值) --> 26 <property 27 name="sdk-folder" 28 value="E:/android-sdk-windows" /> 29 <!-- SDK指定平台目录 --> 30 31 <property 32 name="sdk-platform-folder" 33 value="${sdk-folder}/platforms/android-8" /> 34 <!-- SDK中tools目录 --> 35 36 <property 37 name="sdk-tools" 38 value="${sdk-folder}/tools" /> 39 <!-- SDK指定平台中tools目录 --> 40 41 <property 42 name="sdk-platform-tools" 43 value="${sdk-folder}/platform-tools" /> 44 45 <!-- 使用到的命令(当前系统为windows,如果系统为linux,可将.bat文件替换成相对应的命令) --> 46 47 <property 48 name="aapt" 49 value="${sdk-platform-tools}/aapt" /> 50 51 <property 52 name="aidl" 53 value="${sdk-platform-tools}/aidl" /> 54 55 <property 56 name="dx" 57 value="${sdk-platform-tools}/dx.bat" /> 58 59 <property 60 name="apkbuilder" 61 value="${sdk-tools}/apkbuilder.bat" /> 62 63 <property 64 name="jarsigner" 65 value="${env.JAVA_HOME}/bin/jarsigner" /> 66 67 <property 68 name="zipalign" 69 value="${sdk-tools}/zipalign.exe" /> 70 71 <!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar --> 72 73 <property 74 name="android-jar" 75 value="${sdk-platform-folder}/android.jar" /> 76 77 <property 78 name="android-maps-jar" 79 value="${sdk-folder}/add-ons/addon_google_apis_google_inc_8/libs/maps.jar" /> 80 81 <!-- --> 82 83 <property 84 name="channelname" 85 value="" /> 86 87 <property 88 name="channelkey" 89 value="" /> 90 <!-- 渠道名:渠道号 --> 91 <property 92 name="key" 93 value="qudao1:001,qudao2:002,qudao3:003" /> 94 95 <!-- 编译aidl文件所需的预处理框架文件framework.aidl --> 96 97 <property 98 name="framework-aidl" 99 value="${sdk-platform-folder}/framework.aidl" /> 100 <!-- 清单文件 --> 101 102 <property 103 name="manifest-xml" 104 value="AndroidManifest.xml" /> 105 <!-- 源文件目录 --> 106 107 <property 108 name="resource-dir" 109 value="res" /> 110 111 <property 112 name="asset-dir" 113 value="assets" /> 114 <!-- java源文件目录 --> 115 116 <property 117 name="srcdir" 118 value="src" /> 119 120 <property 121 name="srcdir-ospath" 122 value="${basedir}/${srcdir}" /> 123 <!-- 外部类库所在目录 --> 124 125 <property 126 name="external-lib" 127 value="libs" /> 128 129 <property 130 name="external-lib-ospath" 131 value="${basedir}/${external-lib}" /> 132 133 <!-- 版本 --> 134 135 <property 136 name="version" 137 value="1.0" /> 138 139 <!-- 循环打包 --> 140 141 <target name="deploy" > 142 143 <foreach 144 delimiter="," 145 list="${key}" 146 param="nameandchannel" 147 target="modify_manifest" > 148 </foreach> 149 </target> 150 151 <target name="modify_manifest" > 152 153 <!-- 获取渠道名字 --> 154 155 <propertyregex 156 input="${nameandchannel}" 157 override="true" 158 property="channelname" 159 regexp="(.*):" 160 select="\1" /> 161 <!-- 获取渠道号码 --> 162 163 <propertyregex 164 input="${nameandchannel}" 165 override="true" 166 property="channelkey" 167 regexp=":(.*)" 168 select="\1" /> 169 <!-- 正则匹配替换渠道号 --> 170 171 <replaceregexp 172 byline="false" 173 encoding="UTF-8" 174 flags="g" > 175 176 <regexp pattern="meta-data android:value="(.*)" android:name="app_key"" /> 177 178 <substitution expression="meta-data android:value="${channelkey}" android:name="app_key"" /> 179 180 <fileset 181 dir="" 182 includes="AndroidManifest.xml" /> 183 </replaceregexp> 184 185 <antcall target="zipalign" /> 186 </target> 187 188 <!-- 初始化工作 --> 189 190 <target name="init" > 191 192 <echo> 193 目录初始化.... 194 195 196 </echo> 197 <!-- 生成R文件的相对目录 --> 198 199 <var 200 name="outdir-gen" 201 value="gen" /> 202 <!-- 编译后的文件放置目录 --> 203 204 <var 205 name="outdir-bin" 206 value="bin-${channelname}" /> 207 <!-- 生成class目录 --> 208 209 <var 210 name="outdir-classes" 211 value="${outdir-bin}" /> 212 213 <var 214 name="outdir-classes-ospath" 215 value="${basedir}/${outdir-classes}" /> 216 217 <!-- classes.dex相关变量 --> 218 219 <var 220 name="dex-file" 221 value="classes.dex" /> 222 223 <var 224 name="dex-path" 225 value="${outdir-bin}/${dex-file}" /> 226 227 <var 228 name="dex-ospath" 229 value="${basedir}/${dex-path}" /> 230 231 <!-- 经过aapt生成的资源包文件 --> 232 233 <var 234 name="resources-package" 235 value="${outdir-bin}/resources.ap_" /> 236 237 <var 238 name="resources-package-ospath" 239 value="${basedir}/${resources-package}" /> 240 241 <!-- 未认证apk包 --> 242 243 <var 244 name="out-unsigned-package" 245 value="${outdir-bin}/${appName}-unsigned.apk" /> 246 247 <var 248 name="out-unsigned-package-ospath" 249 value="${basedir}/${out-unsigned-package}" /> 250 251 <!-- 证书文件 --> 252 253 <var 254 name="keystore-file" 255 value="${basedir}/CE_VICTOR.VICTOR" /> 256 257 <!-- 已认证apk包 --> 258 259 <var 260 name="out-signed-package" 261 value="${outdir-bin}/${appName}-${channelname}-${version}.apk" /> 262 263 <var 264 name="out-signed-package-ospath" 265 value="${basedir}/${out-signed-package}" /> 266 267 <delete dir="${outdir-bin}" /> 268 269 <mkdir dir="${outdir-bin}" /> 270 271 <mkdir dir="${outdir-classes}" /> 272 </target> 273 274 <!-- 根据工程中的资源文件生成R.java文件 --> 275 276 <target 277 name="gen-R" 278 depends="init" > 279 280 <echo> 281 生成R.java文件.... 282 283 284 </echo> 285 286 <exec 287 executable="${aapt}" 288 failonerror="true" > 289 290 <arg value="package" /> 291 292 <arg value="-f" /> 293 294 <arg value="-m" /> 295 296 <arg value="-J" /> 297 298 <arg value="${outdir-gen}" /> 299 300 <arg value="-S" /> 301 302 <arg value="${resource-dir}" /> 303 304 <arg value="-M" /> 305 306 <arg value="${manifest-xml}" /> 307 308 <arg value="-I" /> 309 310 <arg value="${android-jar}" /> 311 </exec> 312 </target> 313 314 <!-- 编译aidl文件 --> 315 316 <target 317 name="aidl" 318 depends="gen-R" > 319 320 <echo> 321 编译aidl文件.... 322 323 324 </echo> 325 326 <apply 327 executable="${aidl}" 328 failonerror="true" > 329 330 <!-- 指定预处理文件 --> 331 332 <arg value="-p${framework-aidl}" /> 333 <!-- aidl声明的目录 --> 334 335 <arg value="-I${srcdir}" /> 336 <!-- 目标文件目录 --> 337 338 <arg value="-o${outdir-gen}" /> 339 <!-- 指定哪些文件需要编译 --> 340 341 <fileset dir="${srcdir}" > 342 343 <include name="**/*.aidl" /> 344 </fileset> 345 </apply> 346 </target> 347 348 <!-- 将工程中的java源文件编译成class文件 --> 349 350 <target 351 name="compile" 352 depends="aidl" > 353 354 <echo> 355 java源文件编译成class文件.... 356 357 358 </echo> 359 360 <javac 361 bootclasspath="${android-jar}" 362 destdir="${outdir-classes}" 363 encoding="utf-8" 364 srcdir="." 365 target="1.5" 366 verbose="false" > 367 368 <compilerarg line="-encoding GBK " /> 369 370 <classpath> 371 372 <fileset 373 dir="${external-lib}" 374 includes="*.jar" /> 375 </classpath> 376 </javac> 377 </target> 378 379 <!-- 将.class文件转化成.dex文件 --> 380 381 <target 382 name="dex" 383 depends="compile" > 384 385 <echo> 386 将.class文件转化成.dex文件.... 387 388 389 </echo> 390 391 <exec 392 executable="${dx}" 393 failonerror="true" > 394 395 <arg value="--dex" /> 396 <!-- 输出文件 --> 397 398 <arg value="--output=${dex-ospath}" /> 399 <!-- 要生成.dex文件的源classes和libraries --> 400 401 <arg value="${outdir-classes-ospath}" /> 402 403 <arg value="${external-lib-ospath}" /> 404 </exec> 405 </target> 406 407 <!-- 将资源文件放进输出目录 --> 408 409 <target name="package-res-and-assets" > 410 411 <echo> 412 将资源文件放进输出目录.... 413 414 415 </echo> 416 417 <exec 418 executable="${aapt}" 419 failonerror="true" > 420 421 <arg value="package" /> 422 423 <arg value="-f" /> 424 425 <arg value="-M" /> 426 427 <arg value="${manifest-xml}" /> 428 429 <arg value="-S" /> 430 431 <arg value="${resource-dir}" /> 432 433 <arg value="-A" /> 434 435 <arg value="${asset-dir}" /> 436 437 <arg value="-I" /> 438 439 <arg value="${android-jar}" /> 440 441 <arg value="-F" /> 442 443 <arg value="${resources-package}" /> 444 </exec> 445 </target> 446 447 <!-- 打包成未签证的apk --> 448 449 <target 450 name="package" 451 depends="dex, package-res-and-assets" > 452 453 <echo> 454 打包成未签证的apk.... 455 456 457 </echo> 458 459 <exec 460 executable="${apkbuilder}" 461 failonerror="true" > 462 463 <arg value="${out-unsigned-package-ospath}" /> 464 465 <arg value="-u" /> 466 467 <arg value="-z" /> 468 469 <arg value="${resources-package-ospath}" /> 470 471 <arg value="-f" /> 472 473 <arg value="${dex-ospath}" /> 474 475 <arg value="-rf" /> 476 477 <arg value="${srcdir-ospath}" /> 478 </exec> 479 </target> 480 481 <!-- 对apk进行签证 ,因为JDK7会修改签名的默认算法,所以需要指定SHA1 --> 482 483 <target 484 name="jarsigner" 485 depends="package" > 486 487 <echo> 488 Packaging signed apk for release... 489 490 491 </echo> 492 493 <exec 494 executable="${jarsigner}" 495 failonerror="true" > 496 497 <arg value="-verbose" /> 498 499 <arg value="-digestalg" /> 500 501 <arg value="SHA1" /> 502 503 <arg value="-sigalg" /> 504 505 <arg value="MD5withRSA" /> 506 507 <arg value="-keystore" /> 508 509 <arg value="${keystore-file}" /> 510 511 <arg value="-storepass" /> 512 513 <arg value="71ok123zxcasdqwe" /> 514 515 <arg value="-keypass" /> 516 517 <arg value="71ok123zxcasdqwe" /> 518 519 <arg value="-signedjar" /> 520 521 <arg value="${out-signed-package-ospath}" /> 522 523 <arg value="${out-unsigned-package-ospath}" /> 524 525 <!-- 不要忘了证书的别名 --> 526 <arg value="ce" /> 527 </exec> 528 </target> 529 530 <!-- 发布 --> 531 532 <target 533 name="release" 534 depends="jarsigner" > 535 536 <!-- 删除未签证apk --> 537 538 <delete file="${out-unsigned-package-ospath}" /> 539 540 <echo> 541 APK is released. path:${out-signed-package-ospath} 542 543 544 </echo> 545 </target> 546 <!-- 打包的应用程序进行优化 --> 547 548 <target 549 name="zipalign" 550 depends="release" > 551 552 <exec 553 executable="${zipalign}" 554 failonerror="true" > 555 556 <arg value="-v" /> 557 558 <arg value="4" /> 559 560 <arg value="${out-signed-package-ospath}" /> 561 562 <arg value="${out-signed-package-ospath}-zipaligned.apk" /> 563 </exec> 564 </target> 565 566 </project>
该文件需要改动地方:
1)
<project name="time" default="release" >
time的值替换成你的工程名。
2) <taskdef
resource="net/sf/antcontrib/antcontrib.properties" >
<classpath>
<pathelement
location="C:/apache-ant-1.9.4/lib/ant-contrib-1.0b3.jar"
/>
</classpath>
</taskdef>
“C:/apache-ant-1.9.4/lib/ant-contrib-1.0b3.jar”
替换成你存放ant-contrib-1.0b3.jar的地方。
本来这边可以使用环境变量ANT_HOME,但是一直不行,所以改成了绝对路径。
3)
替换你的SDK目录:
<property
name="sdk-folder"
value="E:/android-sdk-windows"
/>
"E:/android-sdk-windows"
替换成你的SDK目录
本来这边可以使用环境变量ANDROID_SDK_HOME,但是一直不行,所以改成了绝对路径。
4)配置渠道名和渠道号:
<property
name="key"
value="qudao1:001,qudao2:002,qudao3:003"
/>
"qudao1:001,qudao2:002,qudao3:003"替换成你要配置渠道名和渠道号。格式:渠道名1:渠道号1,渠道名2:渠道号2,......
5)修改版本号:
<property
name="version"
value="3.0" />
"3.0"
替换成你的版本号。
6)设置签名部分:
<var
name="keystore-file"
value="${basedir}/gaoxin.key"
/>
"${basedir}/gaoxin.key"
替换成的你签名文件的路径
<!-- 对apk进行签证 ,因为JDK7会修改签名的默认算法,所以需要指定SHA1
-->
<target
name="jarsigner"
depends="package" >
<echo>
Packaging signed apk
for release...
</echo>
<exec
executable="${jarsigner}"
failonerror="true"
>
<arg value="-verbose" />
<arg value="-digestalg"
/>
<arg value="SHA1" />
<arg value="-sigalg"
/>
<arg value="MD5withRSA" />
<arg value="-keystore"
/>
<arg value="${keystore-file}" />
<arg value="-storepass"
/>
<arg value="71ok123zxcasdqwe" />
<arg value="-keypass"
/>
<arg value="71ok123zxcasdqwe" />
<arg value="-signedjar"
/>
<arg value="${out-signed-package-ospath}"
/>
<arg value="${out-unsigned-package-ospath}"
/>
<!-- 不要忘了证书的别名 -->
<arg value="gaoxin"
/>
</exec>
</target>
如果你的JDK是7,需要添加红色部分的代码,如果是6,就可以不需要,否则,最终的APK安装会出现“该文件签名有问题,无法安装”。
第一个
<arg value="71ok123zxcasdqwe" /> 替换成你的密钥的密码
第二个
<arg value="71ok123zxcasdqwe" /> 替换成你别名的密码
<arg
value="gaoxin" /> "gaoxin" 替换成你密钥中的别名
7)在AndroidManifest.xml中设置保存渠道号的meta-data:在application中也就是和activity同级
<meta-data android:name="ccccc" android:value="app_key"/>
注意,build.xml文件中的:
<target
name="modify_manifest" >
<!-- 获取渠道名字
-->
<propertyregex
input="${nameandchannel}"
override="true"
property="channelname"
regexp="(.*):"
select="\1"
/>
<!--
获取渠道号码 -->
<propertyregex
input="${nameandchannel}"
override="true"
property="channelkey"
regexp=":(.*)"
select="\1"
/>
<!--
正则匹配替换渠道号 -->
<replaceregexp
byline="false"
encoding="UTF-8"
flags="g"
>
<regexp pattern="meta-data android:value="(.*)"
android:name="app_key""
/>
<substitution expression="meta-data
android:value="${channelkey}"
android:name="app_key""
/>
<fileset
dir=""
includes="AndroidManifest.xml" />
</replaceregexp>
<antcall target="zipalign"
/>
</target>
中的<regexp pattern="meta-data
android:value="(.*)" android:name="app_key""
/>要和你的AndroidManifest.xml的中meta-data字符串格式对应,如果不对应,正则替换就替换不了。
8) 最新的Android SDK
没有文件"apkbuilder.bat",我在网上下载了一个以前版本的,发现用不了,后来找到一个别人根据最新SDK修改过的。
把下载的"apkbuilder.bat"放到“D:\Android\adt-bundle-windows-x86_64-20131030\sdk\tools”中。
9)最新的Android SDK的platform-tools中没有dx.bat和dx.jar文件需要从build-tools下的版本文件中复制出来放到platform-tools中
运行build.xml:
选中deploy,去掉选中release[default],点击运行。
工程目录下多出了3个文件夹:
文件夹里面: