请教cry如何打包apk

android(84)
转载:.cn/s/blog_74c22b.html
1.配置JAVA的环境变量
&&&(参考/article/f9ebef.html),
&&&很多Java程序员由于使用Eclipse不配置Java环境变量也能正常运行代码。但是如果想使用Ant命令批量打包本步骤必不可少。
2.&下载Ant(这里的Ant不是eclipse和android
SDk里面自带的ant)
&&&&&官方下载地址:
3.&解压Ant并配置环境变量
解压Ant,比如解压到D:\ant
&&b) 我的电脑-&属性-&高级-&环境变量
&c) 系统变量新建ANT_HOME,变量值为d:\ant
&d) 系统变量新建或修改PATH:将%ANT_HOME%\%ANT_HOME%\lib添加到环境变量的PATH中 (注意以上
路径均用反斜杠)
4. 验证ant配置是否正确
&&&在控制台输入Cmd 回车, ant 回车,如果出现:
&&&Buildfile: build.xml does not exist!
&&&Build failed
&&&恭喜你已经ant配置成功!!
&&&&Ant批量打包的基本思想是,每次打包后自动替换渠道号,然后再次打包从而实现多渠道打包的目的。
但是Ant不支持循环,怎样循环打包? 扩展包Ant-contrib能轻松解决这个问题.可以翻墙的同学可以到http://ant-contrib.sourceforge.net/自行下载,下载后直接把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 --&
&&&&&&&&&&&&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
&&&&&&&&&&&&&&&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 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&
&delete includeEmptyDirs=&true&& &
&&&&fileset dir=&${out.absolute.dir}& includes=&**/*&/& &&&&&&&&&&
&echo message=&===========================&/&
&/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 &&&(渠道名称,要以逗号分隔,必须在一行内)
8. 最后一步,修改AndroidManifest.xml文件:
&以上这一行必须在同一行内,决不能换行,这是由于在build.xml做了如下限定
9.生成渠道包&
&&a)进入工程根目录,我的为:D:\apps\workspace\ThumbPlay
&&&&&注意这里必须要去工程根目录,因为Ant命令运行需要找到工程根目录下的build.xml
&&&&b)cmd输入命令:ant deploy 第一次运行或许需要的时间要长些,我的为大约2分50秒
&&&&若控制台最后出现Build Success,说明打包成功
&&&&若控制台最后出现Build Failed,查看详细信息,找出错误所在,修改它,然后重新运行命令:ant
再增加一些看到的优秀博文:
ANT英文官方教程:
优秀博文:
&&&&&&&&&&
有些同志还将 jenkins + ant(jenkins就是一个计划任务)联合起来使用。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:161354次
积分:2094
积分:2094
排名:第16771名
原创:49篇
转载:65篇
评论:27条
(2)(3)(3)(6)(4)(5)(1)(1)(2)(2)(2)(3)(3)(1)(3)(1)(1)(1)(1)(2)(3)(2)(3)(2)(2)(1)(1)(2)(6)(7)(2)(1)(9)(9)(5)(2)(11)CRYENGINE5 打包发布教程(含加密)【cryengine吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:907贴子:
CRYENGINE5 打包发布教程(含加密)收藏
资源来自www.gamedeveloper.topCRYENGINE 5项目发布指南一、生成密钥二、C++代码设置三、添加CVar白名单四、编译五、使用密钥加密并打包资源文件为PAK六、复制和删除文件七、补充下载地址:链接: 密码: 9nph
量身定制,全屋智能化装修方案,免费获取!
学习了,5万人关注的曹磊这个人的微信订阅号,每周周末都会送各种IT技术学习资料。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或推荐这篇日记的豆列
······Ant、Gradle、Python三种打包方式的介绍
博客出自:http:
blog csdn net liuxian13183,转载注明出处! All Rights Reserved !今天谈一下Androdi三种打包方式,Ant、Gradle、Python。当然最开始打包用Ant 很方便,后来转Studio开发
今天谈一下Androdi三种打包方式,Ant、Gradle、。
当然最开始打包用Ant 很方便,后来转Studio开发,自带很多Gradle插件就用了它,然后随着打包数量越多,打包时间成了需要考虑的事,前两者平均打一个包要花费2-3分钟,打30个就要差不多2个小时;而前两者打包的思路主要是,替换Manifest.xml的meta-data下的value值,然后重新编译 注:不管Ant还是Gradle,下面这句都要加入AndroidManifest.xml
而Python打包非常快,几百个包5分钟以内搞定,而它的思路仅是打完一个可发布包后,往apk的META-INF下写入一个含渠道名的文件,由应用去解析这个渠道名即可,不再使用传统的meta-data去标识value值。
编译一般有以下几个步骤:
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
-------------------------------------------------------------我是分割线----------------------------------------------------------------------------
一、简单讲一下Ant打包的流程
1、安装ant,并配置好环境变量,在ant-&lib目录下放入一个ant-contrib-1.0b3.jar
2、在主项目和依赖项目目录下放置build.xml和local.properties(依赖文件只用放sdk_dir就行)
3、在主项目目录下放置custom_rules.xml即可
4、在命令行下,进入要打包的主项目目录下,输入ant deploy即可(如果二次打包要先输入ant clean)
build.xml文件如下
主要作用:声明主项目和依赖项目,sdk的位置、用到的文件如local.properties等
local.properties
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Feb 16 16:07:45 CST 2016
sdk.dir=AndroidSdk的位置,例如:D:\\Android_Software\\adt-bundle-windows-x86_64-\\sdk
sdk.platformtools=YourSdkPm
sdk.tools=YourSdkTools
apk.dir=打出包放的位置-打包前要确定此路径存在,且无中文
app_version=版本号
app_name=版本名称
market_channels=渠道号-以逗号隔开
key.store=密钥存储路径-注意双斜杠\\
key.store.password=密码
key.alias=别名
key.alias.password=别名密码
最重要的custom_rules.xml来了
此文件配置获得打包命令,打包渠道,以及修改文件名,最后打包的过程《完》
-------------------------------------------------------------我是分割线----------------------------------------------------------------------------
二、再讲一下Gradle打包的流程
1、配置好build.gradle,如下
2、studio命令行:
gradlew assembleDebug --打非正式包
gradlew assembleRelease --打正式包
gradlew assembleWandoujiaRelease -打特定渠道
signingConfigs {
keyAlias 'your_alias_key'
keyPassword 'your_key_pwd
storePassword 'your_store_pwd'
storeFile file('your_store_key')
keyAlias 'your_alias_key'
storeFile file('your_store_key')
if (System.console() != null) {
keyPassword System.console().readLine("\nKey password: ")
storePassword System.console().readLine("\nKeystore password: ")
buildTypes {
//多余的参数
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.debug
// 显示Log
buildConfigField "boolean", "LOG_DEBUG", "true"
minifyEnabled true//缩小
zipAlignEnabled true
shrinkResources true//删除无用资源
signingConfig signingConfigs.release
// 显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
applicationVariants.all { variant -&
variant.outputs.each { output -&
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 输出apk名称为apkName_v1.0_wandoujia.apk
def fileName = "apkName${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
proguardFile 'your_cfg'--例:E:/SorkSpace/branches/studio/proguard.cfg
productFlavors {
tencent {}
productFlavors.all {
flavor -& flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
compileSdkVersion 19
buildToolsVersion '22.0.1'
sourceSets {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
// Move the build types to build-types/
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src//... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
defaultConfig {
applicationId 'com.chemayi.manager'
versionCode 20
versionName '3.0'
minSdkVersion 10
targetSdkVersion 19
// dex突破65535的限制
multiDexEnabled true
// AndroidManifest.xml 里面UMENG_CHANNEL的value为 ${UMENG_CHANNEL_VALUE}
// manifestPlaceholders = [UMENG_CHANNEL_VALUE: "channel_name"]
dexOptions {
incremental true
javaMaxHeapSize "4g"
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
lintOptions {
abortOnError false
配置比Ant简单多了,当然在命令行也可以打包,只不过将gradle换成gradlew即可
-------------------------------------------------------------我是分割线----------------------------------------------------------------------------
三、Python打包
1、安装python软件
2、在项目中放入ChannelUtil.java类,用来获得渠道号
3、打好一个包放在与MultiChannelBuildTool.py同级目录
4、在.py同级目录info下的channel.txt添加渠道号
5、点击MultiChannelBuildTool.py即可
文件目录:
ChannelUtil.java
package com.blog.
import java.io.IOE
import java.util.E
import java.util.zip.ZipE
import java.util.zip.ZipF
import android.content.C
import android.content.SharedP
import android.content.SharedPreferences.E
import android.content.pm.ApplicationI
import android.content.pm.PackageManager.NameNotFoundE
import android.preference.PreferenceM
import android.text.TextU
public class ChannelUtil {
private static final String CHANNEL_KEY = "yourchannel";
private static final String CHANNEL_VERSION_KEY = "yourchannel_version";
private static String mC
* 返回市场。
如果获取失败返回""
* @param context
public static String getChannel(Context context){
return getChannel(context, "");
* 返回市场。
如果获取失败返回defaultChannel
* @param context
* @param defaultChannel
public static String getChannel(Context context, String defaultChannel) {
//内存中获取
if(!TextUtils.isEmpty(mChannel)){
//sp中获取
mChannel = getChannelBySharedPreferences(context);
if(!TextUtils.isEmpty(mChannel)){
//从apk中获取
mChannel = getChannelFromApk(context, CHANNEL_KEY);
if(!TextUtils.isEmpty(mChannel)){
//保存sp中备用
saveChannelBySharedPreferences(context, mChannel);
//全部获取失败
return defaultC
* 从apk中获取版本信息
* @param context
* @param channelKey
private static String getChannelFromApk(Context context, String channelKey) {
//从apk包中获取
ApplicationInfo appinfo = context.getApplicationInfo();
String sourceDir = appinfo.sourceD
//默认放在meta-inf/里, 所以需要再拼接一下
String key = "META-INF/" + channelK
String ret = "";
ZipFile zipfile =
zipfile = new ZipFile(sourceDir);
Enumeration entries = zipfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
if (entryName.startsWith(key)) {
ret = entryN
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
String[] split = ret.split("_");
String channel = "";
if (split != null && split.length &= 2) {
channel = ret.substring(split[0].length() + 1);
* 本地保存channel & 对应版本号
* @param context
* @param channel
private static void saveChannelBySharedPreferences(Context context, String channel){
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sp.edit();
editor.putString(CHANNEL_KEY, channel);
editor.putInt(CHANNEL_VERSION_KEY, getVersionCode(context));
* 从sp中获取channel
* @param context
* @return 为空表示获取异常、sp中的值已经失效、sp中没有此值
private static String getChannelBySharedPreferences(Context context){
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
int currentVersionCode = getVersionCode(context);
if(currentVersionCode == -1){
//获取错误
return "";
int versionCodeSaved = sp.getInt(CHANNEL_VERSION_KEY, -1);
if(versionCodeSaved == -1){
//本地没有存储的channel对应的版本号
//第一次使用
或者 原先存储版本号异常
return "";
if(currentVersionCode != versionCodeSaved){
return "";
return sp.getString(CHANNEL_KEY, "");
* 从包信息中获取版本号
* @param context
private static int getVersionCode(Context context){
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionC
}catch(NameNotFoundException e) {
e.printStackTrace();
return -1;
MultiChannelBuildTool.py
#!/usr/bin/python
# coding=utf-8
import zipfile
import shutil
# 空文件 便于写入此空文件到apk包中作为channel文件
src_empty_file = 'info/yourchannel_.txt'
# 创建一个空文件(不存在则创建)
f = open(src_empty_file, 'w')
# 获取当前目录中所有的apk源包
src_apks = []
# python3 : os.listdir()即可,这里使用兼容Python2的os.listdir('.')
for file in os.listdir('.'):
if os.path.isfile(file):
extension = os.path.splitext(file)[1][1:]
if extension in 'apk':
src_apks.append(file)
# 获取渠道列表
channel_file = 'info/channel.txt'
f = open(channel_file)
lines = f.readlines()
for src_apk in src_apks:
# file name (with extension)
src_apk_file_name = os.path.basename(src_apk)
# 分割文件名与后缀
temp_list = os.path.splitext(src_apk_file_name)
# name without extension
src_apk_name = temp_list[0]
# 后缀名,包含.
例如: ".apk "
src_apk_extension = temp_list[1]
# 创建生成目录,与文件名相关
output_dir = 'output_' + src_apk_name + '/'
# 目录不存在则创建
if not os.path.exists(output_dir):
os.mkdir(output_dir)
# 遍历渠道号并创建对应渠道号的apk文件
for line in lines:
# 获取当前渠道号,因为从渠道文件中获得带有\n,所有strip一下
target_channel = line.strip()
# 拼接对应渠道号的apk
target_apk = output_dir + src_apk_name + "_" + target_channel + src_apk_extension
# 拷贝建立新apk
shutil.copy(src_apk,
target_apk)
# zip获取新建立的apk文件
zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)
# 初始化渠道信息
empty_channel_file = "META-INF/yourchannel_{channel}".format(channel = target_channel)
# 写入渠道信息
zipped.write(src_empty_file, empty_channel_file)
# 关闭zip流
zipped.close()
channel.txt

我要回帖

更多关于 maven项目如何打包war 的文章

 

随机推荐