最新的Android Sdk 使用Ant多渠道批量打包

时间:2022-11-05 12:01:20

实例工程、所需的文件都在最后的附件中。

    今天花费了几个小时,参考网上的资料,期间遇到了好几个问题, 终于实现了使用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=&quot;(.*)&quot; android:name=&quot;app_key&quot;" />
177
178 <substitution expression="meta-data android:value=&quot;${channelkey}&quot; android:name=&quot;app_key&quot;" />
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=&quot;(.*)&quot; android:name=&quot;app_key&quot;" />

            <substitution expression="meta-data android:value=&quot;${channelkey}&quot; android:name=&quot;app_key&quot;" />

            <fileset
                dir=""
                includes="AndroidManifest.xml" />
        </replaceregexp>

        <antcall target="zipalign" />
    </target>

中的<regexp pattern="meta-data android:value=&quot;(.*)&quot; android:name=&quot;app_key&quot;" />要和你的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:

最新的Android Sdk 使用Ant多渠道批量打包

最新的Android Sdk 使用Ant多渠道批量打包

选中deploy,去掉选中release[default],点击运行。

工程目录下多出了3个文件夹:

最新的Android Sdk 使用Ant多渠道批量打包

文件夹里面:

最新的Android Sdk 使用Ant多渠道批量打包