Android使用Ant进行apk多渠道打包
Android使用Ant进行apk多渠道打包
前言:
Ant 是什么?
详细介绍请看http://ant.apache.org/
总之一句话:Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能。
准备工作:
android sdk中默认支持使用ant来执行编译动作。但是要想使用ant来进行编译,还需要ant的执行环境。
为了能顺利使用ant来编译,我们需要如下准备:
1,android sdk,最简单的是下载一个adt bundle即可;
2,ant包,下载链接:http://ant.apache.org/bindownload.cgi,将压缩包下载完解压到某个目录即可。
3,ant-contrib.jar,这个jar主要用来支持编译的批量操作,下载地址http://mirrors.ibiblio.org/maven2/ant-contrib/ant-contrib/1.0b3/ant-contrib-1.0b3.jar,下完之后放到步骤2解压目录的lib目录。
参考:
关于android编译生成apk的流程,可以参照http://www.oschina.net/code/snippet_16_6782,
其实有个偷懒的方式,就是借用 android sdk的tools/ant/目录中build.xml文件内已定义好的动作,主要是用到”release”。
下面主要介绍一下基于已定义好的release,怎么修改实现自己的build.xml文件。
步骤:
首先介绍一下build.xml文件中变量的定义格式如下,后面会用到
1 <property name=”key_sample” value=”value_sample” />
1,对生成目录做必要的清除动作,起名为myClean,这里我删除了生成目录下的所有apk文件。
1 <target name="myClean">
2 <mkdir dir="${outputDir}"/>
3 <delete verbose="true">
4 <fileset dir="${outputDir}" includes="*.apk" />
5 </delete>
6 </target>
outputDir是我事先定义好的变量:
1 <property name=”outputDir” value=”../output”/>
2,加载渠道信息,并使用ant的 foreach功能实现批量打包;
1 <target name="myPackChannels">
2 <foreach target="myPackBuild" list="${build.channels}" param="build.channel" delimiter=",">
3 </foreach>
4 </target>
可以看到这里是从 ${build.channels} 中读取相关渠道信息,多渠道中间用,分隔;
build.channels=101,201,301
3,将当前的AndroidMenifest.xml复制到备份目录;
1 <target name="myBackupManifest">
2 <delete file="${build}/${manifest}" />
3 <copy file="${manifest}" tofile="${build}/${manifest}" overwrite="true"/>
4 </target>
4,修改当前的AndroidMenifest.xml里面的内容,比如channel值;
1 <target name="myPrepareBuildinfo" depends="myLoadBuildInfo">
2 <replaceregexp flags="g" byline="true" encoding="UTF-8">
3 <regexp pattern='android:versionCode="(.*)"' />
4 <substitution expression='android:versionCode="${buildVersionCode}"' />
5 <fileset dir="" includes="${manifest}" />
6 </replaceregexp>
7 <replaceregexp flags="g" byline="true" encoding="UTF-8">
8 <regexp pattern='android:versionName="(.*)"' />
9 <substitution expression='android:versionName="${buildVersionName}"' />
10 <fileset dir="" includes="${manifest}" />
11 </replaceregexp>
12 <replaceregexp flags="g" byline="true" encoding="UTF-8">
13 <regexp pattern='android:value="@string/APP_CHANNEL"'/>
14 <substitution expression='android:value="${build.channel}"'/>
15 <fileset dir="" includes="${manifest}" />
16 </replaceregexp>
17 </target>
我这里执行了修改versionName,versionCode和APP_CHANNEL这三个值。
5,执行release动作;
6,针对4生成的unsigned apk 用自己的签名文件签名;
1 <!-- 签名 -->
2 <target name="mySign">
3 <mkdir dir="${outputDir}"/>
4 <java jar="${signjar}" fork="true" failonerror="true" maxmemory="128m">
5 <arg value="-w"/>
6 <arg value="${key_pem}"/>
7 <arg value="${key_pk8}"/>
8 <arg value="${binDir}/${build.name}-release-unsigned.apk"/>
9 <arg value="${binDir}/${build.name}-release-signed.apk"/>
10 <classpath>
11 <pathelement location="${signjar}"/>
12 </classpath>
13 </java>
14
15 <property name="outName" value="${outputDir}/${build.name}-${buildVersionName}-${buildVersionCode}-${build.channel}-${build.timestamp}-${buildNumber}"/>
16
17
18 <zipalign-helper in.package="${binDir}/${build.name}-release-unsigned.apk"
19 out.package="${outName}.apk" />
20 <copy file="${mapping}" tofile="${outName}-mapping.txt" overwrite="true"/>
21 </target>
7,repeat step3,4,5;(这就是动作2 foreach的执行)
8,恢复之前备份的AndroidMenifest.xml到当前目录;
1 <target name="myRestoreManifest">
2 <copy file="${build}/${manifest}" tofile="${manifest}" overwrite="true"/>
3 <delete file="${build}/${manifest}" />
4 </target>
最后,整理一下要执行的步骤:
1 <target name=".output" depends="myClean, myBackupManifest, myLoadBuildInfo, myPackChannels, myRestoreManifest,myUpdateBuilderNumber">
2 </target>
so,在你的build.xml所在的目录,执行ant .output 即可,大功告成!
- MongoDB文档查询操作(三)
- MongoDB文档查询操作(二)
- MongoDB文档查询操作(一)
- Docker容器跨主机互联
- 堆,栈,内存泄露,内存溢出介绍
- MongoDB文档更新操作
- JS模块与命名空间的介绍
- MongoDB数据类型
- Spring Boot 之Application.properties配置大全
- Machine Learning Notes-Decision Trees-Udacity
- MongoDB基本操作
- Linux上安装MongoDB
- MongoDB中MapReduce使用
- Machine Learning Notes-Linear Regression-Udacity
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- C++核心准则CP.100:不要使用无锁编程方式,除非绝对必要
- 神了,Excel的这个操作我今天才知道
- DataFrame(7):DataFrame运算——逻辑运算
- 高性能网关设计实践
- LASSO回归姊妹篇:R语言实现岭回归分析
- 学了这个,三歪再也不想写各种setter了
- 使用 GitLab CI 与 Argo CD 进行 GitOps 实践
- Java 语言中十大“坑爹”功能!
- 面试:说说啥是一致性哈希算法?
- 问一下,线程池里面到底该设置多少个线程?
- 进程和线程基础知识全家桶,30 张图一套带走
- Python-matplotlib 学术柱状图绘制
- 为什么要避免大事务以及大事务如何解决?
- [即时通信IM]群@消息如何实现?
- 利用PySpark对 Tweets 流数据进行情感分析实战