android 如何优化ant 批量打包

作者&投稿:恽胁 (若有异议请与网页底部的电邮联系)
android如何使用ant批量打包~

ps :后期熟悉ant的话,可以使用纯ant脚本或者使用另一种更好的自动化打包工具(maven)关键代码如下:package com.cn.ant; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import org.apache.tools.ant.DefaultLogger; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; public class AntTest { private Project project; public void init(String _buildFile, String _baseDir) throws Exception { project = new Project(); project.init(); DefaultLogger consoleLogger = new DefaultLogger(); consoleLogger.setErrorPrintStream(System.err); consoleLogger.setOutputPrintStream(System.out); consoleLogger.setMessageOutputLevel(Project.MSG_INFO); project.addBuildListener(consoleLogger); // Set the base directory. If none is given, "." is used. if (_baseDir == null) _baseDir = new String("."); project.setBasedir(_baseDir); if (_buildFile == null) _buildFile = new String(projectBasePath + File.separator + "build.xml"); //ProjectHelper.getProjectHelper().parse(project, new File(_buildFile)); // 关键代码 ProjectHelper.configureProject(project, new File(_buildFile)); } public void runTarget(String _target) throws Exception { // Test if the project exists if (project == null) throw new Exception( "No target can be launched because the project has not been initialized. Please call the 'init' method first !"); // If no target is specified, run the default one. if (_target == null) _target = project.getDefaultTarget(); // Run the target project.executeTarget(_target); } // private final static ArrayList flagList = new ArrayList(); //也可以使用集合,不过需要手动添加项 private final static String[] flagList = new String[]{"htc","moto","oppo"};//此处初始化市场标识 private final static String projectBasePath = ""; //项目的根目录,需要配置 private final static String copyApkPath = ""; //要改名后拷贝的目录,需要配置 private final static String placeHolder = ""; //占位符,需要配置 public static void main(String args[]) { //flagList.add("htc"); //flagList.add("moto"); //flagList.add("oppo"); try { System.out.println("---------ant批量自动化打包开始----------"); for(String flag : flagList){ //先修改manifest文件:读取临时文件中的@market@修改为市场标识,然后写入manifest.xml中 String tempFilePath = projectBasePath + File.separator + "AndroidManifest.xml.temp"; String filePath = projectBasePath + File.separator + "AndroidManifest.xml"; write(filePath,read(tempFilePath, flag)); //执行打包命令 AntTest mytest = new AntTest(); mytest.init( projectBasePath + File.separator + "build.xml", projectBasePath); mytest.runTarget("clean"); mytest.runTarget("release"); //打完包后执行重命名加拷贝操作 //String flag = "htc"; File file = new File(projectBasePath + File.separator +"bin"+File.pathSeparator+"MainActivity-release.apk");//bin目录下签名的apk文件 file.renameTo(new File(copyApkPath + File.separator + "MainActivity_"+flag+".apk")); } System.out.println("---------ant批量自动化打包结束----------"); } catch (Exception e) { e.printStackTrace(); System.out.println("---------ant批量自动化打包中发生异常----------"); } } public static String read(String filePath,String replaceStr) { BufferedReader br = null; String line = null; StringBuffer buf = new StringBuffer(); try { // 根据文件路径创建缓冲输入流 br = new BufferedReader(new FileReader(filePath)); // 循环读取文件的每一行, 对需要修改的行进行修改, 放入缓冲对象中 while ((line = br.readLine()) != null) { // 此处根据实际需要修改某些行的内容 if (line.contains(placeHolder)) { line = line.replace(placeHolder, replaceStr); buf.append(line); } else { buf.append(line); } buf.append(System.getProperty("line.separator")); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 if (br != null) { try { br.close(); } catch (IOException e) { br = null; } } } return buf.toString(); } /** * 将内容回写到文件中 * * @param filePath * @param content */ public static void write(String filePath, String content) { BufferedWriter bw = null; try { // 根据文件路径创建缓冲输出流 bw = new BufferedWriter(new FileWriter(filePath)); // 将内容写入文件中 bw.write(content); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 if (bw != null) { try { bw.close(); } catch (IOException e) { bw = null; } } } } }

通常我们习惯用eclipse来开发android程序,它会自动帮我们打包当前的应用程序。如果在Navigator视图下,我们可以看到以下几个文件:

com包放置的是我们的class文件,classes.dex是class文件经过转换后的可以在dalvik上跑的精简类文件,resources.ap_是经过打包的资源文件,ant.apk就是最终的打包文件。
使用ANT来对应用打包,一般会经过以下几个步骤:
1.用aapt命令生成R.Java文件
2.用aidl命令生成相应java文件

3.用javac命令编译java源文件生成class文件

4.用dx.bat将class文件转换成classes.dex文件

5.用aapt命令生成资源包文件resources.ap_

6.用apkbuilder.bat打包资源和classes.dex文件,生成unsigned.apk

7.用jarsinger命令对apk认证,生成signed.apk

1.配置JAVA的环境变量

很多Java程序员由于使用Eclipse不配置Java环境变量也能正常运行代码。但是如果想使用Ant命令批量打包本步骤必不可少。
2. 下载Ant(这里的Ant不是eclipse和android SDk里面自带的ant)

3. 解压Ant并配置环境变量
a) 解压Ant,比如解压到D:\ant
b) 我的电脑->属性->高级->环境变量
c) 系统变量新建ANT_HOME,变量值为d:\ant
d) 系统变量新建或修改PATH:将%ANT_HOME%\bin;%ANT_HOME%\lib添加到环境变量的PATH中 (注意以上
路径均用反斜杠)

4. 验证ant配置是否正确
在控制台输入Cmd 回车, ant 回车,如果出现:
Buildfile: build.xml does not exist!
Build failed
恭喜你已经ant配置成功!!
Ant批量打包的基本思想是,每次打包后自动替换渠道号,然后再次打包从而实现多渠道打包的目的。
但是Ant不支持循环,怎样循环打包? 扩展包Ant-contrib能轻松解决这个问题.可以翻墙的1.0b3.jar放到Ant的lib文件夹即可.

5. 编写build.xml
将以下带有颜色的字体(包括路径,项目名称)都改成正确的名称
<?xml version="1.0" encoding="UTF-8"?>
<project name="ThumbPlay" default="help">

<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />

<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:

source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.

For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml

Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.

This file is an integral part of the build system for your
application and should be checked into Version Control Systems.

-->
<property file="ant.properties" />

<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.

This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).

This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />

<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
unless="sdk.dir"
/>

<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>

<target name="-post-compile">
</target>
-->

<!-- Import the actual build file.

To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.

***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="D:/androidDev/batch-package-tool/ant1.8.3/lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<import file="${sdk.dir}/tools/ant/build.xml" />

<target name="deploy">
<foreach target="modify_manifest" list="${market_channels}" param="channel" delimiter=",">
</foreach>
</target>

<target name="modify_manifest">
<!--<replaceregexp file="AndroidManifest.xml" encoding="utf-8" match="android:value="(.*)"" replace=""/>-->
<replaceregexp flags="g" byline="false">
<regexp pattern="android:name="UMENG_CHANNEL" android:value="(.*)"" />
<substitution expression="android:name="UMENG_CHANNEL" android:value="${channel}"" />
<fileset dir="" includes="AndroidManifest.xml" />
</replaceregexp>
<!--<property name="out.release.file" value="${out.absolute.dir}/${channel}.apk"/>-->
<antcall target="release"/>
<copy tofile="${gos.path}/ThumbPlay_${channel}.apk">
<fileset dir="${out.absolute.dir}/" includes="ThumbPlay-release.apk" />
</copy>
<delete includeEmptyDirs="true">
<fileset dir="${out.absolute.dir}" includes="**/*"/>
</delete>
<echo message="==========================="/>
</target>
</project>
6. 配置local.properties
sdk.dir=D:\\androidDev\\android-sdk 改成你的SDK所在的目录,注意转义字符
7. 配置ant.properties
# the config file for batch package.
application.package=com.leyou.thumb (你的apk文件的包名)
ant.project.name=ThumbPlay (你的apk文件的工程名)
java.encoding=utf-8
out.absolute.dir=C:/compile
gos.path=Z:/app-version/test (打好的渠道包要放到的目的位置)
key.store=D:/androidApk/thumbplay/thumbplay.keystore (keystore文件路径)
key.store.password=wushenshiji999 (keystore文件路径)
key.alias=muzhigame (keystore文件别名)
key.alias.password=wushenshiji999 (keystore文件别名密码)
app_version=1.0.4 (要打的渠道包的版本名称)
market_channels=guanwang,shuihu,wushen,shenhua,huawei (渠道名称,要以逗号分隔,必须在一行内)

ant 实现批量打包android应用

很多的应用中需要加上应用推广的统计,如果一个一个的去生成不同渠道包的应用,效率低不说,还有可能不小心弄错了分发渠道,使用ant可以批量生成应用。
一、添加渠道包信息

为了统计渠道信息,就不得不在程序的某个地方加入渠道的信息,然后针对不同的渠道打不同的包。一般可以在Manifest文件中加入渠道编号,而不直接写在代码中。这样做的好处是,可以针对不同渠道,自动化去修改Manifest文件中的渠道编号,然后自动为该渠道打包。
Manifest文件支持Meta Data标签,建议使用这种自定义标签。例如下面的文件片段。

[html] view plaincopyprint?
<meta-data android:value="000000" android:name="CHANNEL"/>

二、渠道包读取
[java] view plaincopyprint?
public static String getChanel(Context ctx){
String CHANNELID="000000";
try {
ApplicationInfo ai = ctx.getPackageManager().getApplicationInfo(
ctx.getPackageName(), PackageManager.GET_META_DATA);
Object value = ai.metaData.get("");
if (value != null) {
CHANNELID= value.toString();
}
} catch (Exception e) {
//
}

return CHANNELID;
}

三、自动打包实现
Ant编译android程序 简单介绍了使用ant命令打包android程序,实现批量打包需要的加一个类似于for循环的功能即可,在Ant的核心包里没有相关的For循环的Task,要下载相应的扩展包。可以使用开源的Ant-contrib包。下载地址:http://ant-contrib.sourceforge.net/ 。下载后的解压得到的jar文件放到ant的lib目录。
在build.xml中增加如下代码就可以实现批量打包:

[html] view plaincopyprint?
taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<target name="deploy">
<foreach target="modify_manifest" list="${market_channels}" param="channel" delimiter=",">
</foreach>
</target>
<target name="modify_manifest">
<replaceregexp flags="g" byline="false">
<regexp pattern="android:value="(.*)" android:name="CHANNEL"" />
<substitution expression="android:value="${channel}" android:name="CHANNEL"" />
<fileset dir="" includes="AndroidManifest.xml" />
</replaceregexp>
<property name="out.release.file"
location="${out.absolute.dir}/${ant.project.name}_${channel}_${app_version}.apk" />
<antcall target="release" />
</target>

taskdef 声明需要放到较前位置,因为if condition也会用到此声明。
build.properties文件增加:

taskdef 声明需要放到较前位置,因为if condition也会用到此声明。
build.properties文件增加:

[html] view plaincopyprint?
market_channels=000000,012345
app_version=1.2.1
market名称用逗号分隔
执行ant deploy即可。

/**
* @author 张兴业
* 邮箱:xy-zhang#163.com
* android开发进阶群:278401545
*
*/


玛曲县15335309336: 如何使用android自带的ant -
丰别醋酸: Ant是android的编译打包工具,一个很好的跨平台构建工具,特别是对于Java项目,这里使用它对Android工程进行自动化构建可以得到非常大的便利.一般来说对Android工程进行构.使用Ant搭建Android开发环境,建立android项目 配置Ant环...

玛曲县15335309336: 如何将android原生应用改成ant方式编译 -
丰别醋酸: android 程序打包成apk,如果在是命令行方式,一般都要经过如下步骤:1.用aapt命令生成R.java文件2.用aidl命令生成相应java文件3.用javac命令编译java源文件生成class文件4.用dx.bat将class文件转换成classes.dex文件5.用aapt命令生成资源...

玛曲县15335309336: 如何设置android studio run release -
丰别醋酸: 1. 在Android studio左侧边栏点开Build Variants2. 找到对应的Module,将它的Build Variant从debug改成release3. 在project栏右键选中的Module,打开Open Module Settings4. 在signing栏中填入release对应的配置信息release config,在Build Types的Debuggable设为false(关於release config 主要填写config Name 、release key 以及psw等信息,store file需要自己的jks文件路径),完成后点OK保存5. 编译后即可产生release apk

玛曲县15335309336: ant 编译android 自动增加basedir,如何去除? -
丰别醋酸: build.xml 中有没有关于${android-jar},basedir 定义! 1.标签 每个构建文件对应一个项目.标签时构建文件的根标签.它可以有多个内在属性,就如代码中所示,其各个属性的含义分别如下. (1) default表示默认的运行目标,这个属性是必须的. (2) basedir表示项目的基准目录. (3) name表示项目名. (4) description表示项目的描述. 每个构建文件都对应于一个项目,但是大型项目经常包含大量的子项目,每一个子项目都可以有自己的构建文件.

玛曲县15335309336: ant 脚本中如何设置jdk的路径 -
丰别醋酸: 方法1: 直接修改ANT的运行文件:ant.bat ,设置JAVA_HOME,这样所有的ANT都使用设定的JDK也是一种方法; 我以前做Jetty也是这么做的,挺方便; 方法2:<javac srcdir="${src}"destdir="${build}"fork="yes"executable="/opt/java/jdk1.1/bin/javac"compiler="javac1.5"/> 这样就可以制定特定的java编译器了

玛曲县15335309336: 使用ant脚本打包android项目,包含library项目,如何设置依赖项目? -
丰别醋酸: 设置方法如下:1.生成R.java类文件: Eclipse中会自动生成R.java,ant和命令行使用android SDK提供的aapt.ext程序生成R.java;2.将.aidl文件生成.java类文件: Eclipse中自动生成,ant和命令行使用android SDK提供的aidl.exe生成.java文件; 3....

玛曲县15335309336: 怎么制作安卓系统的本脚就像windows的批处理 主要用来优化 -
丰别醋酸: 安装GScript,使用这个软件可以执行脚本,并且其自身也带了一些实用的脚本,如普通重启、重启到bootloader、重启到recovery等等. 安卓是在LINUX上开发的,所以底层都是LINUX的命令,用GScript可以自己编辑SH脚本的. 如: rm /system/app/BlurEmail.apk rm /system/app/BlurEmail.odex 这是删除电子邮件 rm /system/app/VideoPlayer.apk rm /system/app/VideoPlayer.odex 这是视频播放器,如果安装了第三方的播放软件,这个就可以删除了. 品牌不一样,这些软件的名称也会不同的.

玛曲县15335309336: Android中用ANT打包如何将内容复制到AndroidManifest文件中 -
丰别醋酸: 抱歉,我也不会从 ant 里面去修改,给你个目前我在用的变通的方法.用 sh 脚本(linux/cygwin)或者 批处理(Windows),先修改想要修改的东西,再调用 ant build想要对文件做什么修改,就直接在脚本中完成了

玛曲县15335309336: 如何使用Android Studio提高App质量 -
丰别醋酸: Android Studio作为现在谷歌主推的Android开发功能,除了提供了大量的功能帮助快速开发Android代码之外,在代码质量控制方面也提供了很多工具,这些工具都放在Analyze菜单下, 主要有Inspect Code, Code CleanUp,Analyze ...

玛曲县15335309336: 如何将Android adb 命令写成一个批处理文件 -
丰别醋酸: 首先确保android-sdk 下tools目录加入到环境变量中 如果没有 也行!下面以android-sdk目录为c:\\android-sdk-windows为例 @echo off echo 正在复制文件,请稍等......cd c:\android-sdk-windows\tools\ //如果该目录以加到环境变量 这行就不用啦 adb push c:\1.png /sdcard/1.png adb push c:\2.png /sdcard/2.png echo 复制文件完成!echo. & pause 将上面文件复制到 文本文件,修改扩展名 .bat 直接运行即可完成复制

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网