Ant 打包安卓 apk(5) 多渠道(配置)打包方案 ant 脚本

直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="init" basedir=".">
<description>
simple example build file
</description>

<!-- 使用第三方的 ant 包,使 ant 支持 for 循环-->
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${env.ANT_HOME}/lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>

<!-- set global properties for this build -->
<property file="build.properties" />

<property name="inDir" location="in"/>
<property name="outDir" location="out"/>
<property name="build-tools" location="android-sdk/build-tools/27.0.3"/>
<property name="netease-tools" location="netease-tools"/>

<property name="apksigner.jar" location="${build-tools}/lib/apksigner.jar"/>
<property name="makechannels.jar" location="${netease-tools}/makechannels.jar"/>
<property name="netease-apksigner.jar" location="${netease-tools}/apksigner.jar"/>

<property name="appName.apk" value="${inDir}/${appName}"/>
<!-- 多渠道打包配置 -->
<property name="channels.txt" location="${inDir}/channels.txt"/>
<!-- keystore 配置 -->
<property name="key.store.path" location="${inDir}/${key.store}"/>

<property name="zipalign" value="${build-tools}/zipalign" />

<!-- Create the time stamp -->
<tstamp>
<format property="DSTAMP" pattern="yyMMdd" timezone="GMT+8"/>
</tstamp>

<target name="init">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="verifyApk" description="checking whether signatures of APK files will verify on Android devices.">
<!-- Cannot execute a jar in non-forked mode. Please set fork='true'. -->
<java jar="${apksigner.jar}" fork="true">
<arg value="verify" />
<arg value="--verbose" />
<arg value="${appName.apk}" />
</java>
</target>

<target name="zipalignCheck">
<exec executable="${zipalign}">
<arg value="-c" />
<arg value="-v" />
<arg value="4" />
<arg value="${appName.apk}" />
</exec>
</target>

<target name="makechannels" description="makechannel info each">
<java jar="${makechannels.jar}" fork="true">
<arg value="-apk" />
<arg value="${appName.apk}" />
<arg value="-config" />
<arg value="${channels.txt}" />
<arg value="-out" />
<arg value="${outDir}" />
</java>
</target>

<target name="apksigner" description="可重新签名单个文件 或 文件夹">
<java jar="${netease-apksigner.jar}" fork="true">
<arg value="-appname" />
<arg value="test" />
<arg value="-keystore" />
<arg value="${key.store.path}" />
<arg value="-pswd" />
<arg value="${key.store.password}" />
<arg value="-alias" />
<arg value="${key.alias}" />
<arg value="-aliaspswd" />
<arg value="${key.alias.password}" />
<arg value="-v1" />
<arg value="true" />
<arg value="-v2" />
<arg value="false" />
<arg value="${outDir}" />
</java>
</target>

<target name="zipalignItem" description="对单个文件进行zipalign">
<echo>取出原始${itemAppName}</echo>

<!-- 通过${itemAppName}构建${newApkName} -->
<loadresource property="newApkName" encoding="UTF-8">
<string value="${itemAppName}" />
<filterchain>
<tokenfilter>
<!-- 巧妙将后缀.apk加上了时间 -->
<replaceregex pattern=".apk" replace="_zipalign.apk" flags="g" />
</tokenfilter>
</filterchain>
</loadresource>
<echo>开始构建${newApkName}</echo>
<exec executable="${zipalign}">
<arg value="-f" />
<arg value="-v" />
<arg value="4" />
<arg value="${itemAppName}" />
<arg value="${newApkName}" />
</exec>
</target>

<target name="easyChannels">
<!-- 0. 清理历史数据 -->
<antcall target="clean" />

<!-- 1. 根据channels文件进行多渠道打包 -->
<antcall target="makechannels" />

<!-- 2. 集体重新签名 -->
<antcall target="apksigner" />

<!-- 3. 遍历并zipalign -->
<foreach param="itemAppName" target="zipalignItem">
<path>
<fileset dir="${outDir}">
<include name="*.apk"/>
</fileset>
</path>
</foreach>
</target>

<target name="clean" description="clean up">
<!-- 避免删除了重复删除文件夹的尴尬, 有必要吗? -->
<delete>
<fileset dir="${outDir}" />
</delete>
</target>

</project>

优点:

  • 并不是说ant淘汰了, 由于不参与构建apk, 只是拿到apk包到重新多渠道后签名和zipalign优化, 速度还是比较可观的.

笔记:

  • 需要提交配置好环境变量
  • 日期时间戳 dstamp、tsdamp、today 的应用, 尼玛 HH:mm 才是二十四小时, hh:mm 是十二小时制
  • FilterChain 是个好东西, 本来对于正则表达式理解的不深, 然后 ant 对 Properties 的 value 这种字符串无从下手的时候, 万能的搜索帮了大忙

小疑惑:

  • 采用删除文件下所有文件, 而不是包括文件夹, 我想知道这个有没有必要

参考