Android cocos2d-x 批量打包

用 Eclipse 来给Android 打包是很考验耐心的事


领导布置了任务给好多渠道,好多应用打包


网上有不少方案,参考了一些。


反复调试之后,记录下操作步骤和脚本。


一、 首先要安装 Ant 

对于Android外行的我来说, Ant 也是外行,所以一开始就有一种特别强烈的排斥感 ,想着是否有方法不调用 Ant 。首先试想着正常打出一个包,然后用脚本把包解开,然后修改 AndroidManifest.xml 文件,修改包名,渠道名等,然后再加签。后来反复想了下有好几处难走通,还是用 Ant 来做重复打包的工作吧。

安装完 Ant 之后,发现好简单啊。。。

我在 Mac os 上安装的

下载地址  : http://ant.apache.org/bindownload.cgi

下载完后解压,将包考到 /usr/local 下。

打开 Terminal


Sudo -s
chmod +w /etc/bashrc
vi /etc/bashrc



在文件最后输入环境变量(为免麻烦,把 Android Home 和 NDK_HOME 什么的也都设置进来,注意改成自己的路径)。


export ANDROID_HOME=/Users/xxxxx/Documents/tools/androidsdk/adt-bundle-mac-x86_64-20130219/sdk
export PATH=${PATH}:${ANDROID_HOME}/platform-tools
export PATH=${PATH}:${ANDROID_HOME}/tools
export NDK_HOME=/Users/xxxxxx/Documents/tools/androidsdk/android-ndk-r8e
export PATH=${PATH}:${NDK_HOME}
export NDK_ROOT=$NDK_HOME
export ANT_HOME=/usr/local/apache-ant-1.9.3
export PATH=${PATH}:${ANT_HOME}/bin



然后就好用了!


二、增加 Ant 调用所需要的配置文件

在终端,进入android工程目录,输入

android update project -p xxxxx

其中 xxxxx 是工程路径


 执行完毕后,会生成几个文件。暂不管。另外要手动添加一个文件 custom_rules.xml 文件。这个文件在 build.xml 里面会被调用。 Ant 的入口是 build.xml ,然后再进入 custom_rules.xml ,这个文件就是我们打包可以做文章的地方。(其实也可以在 sh 上实现渠道的修改)



在  ant.properties 文件里面输入签名要用到的用户名和密码

key.store=key path
key.store.password=password
key.alias=alias name
key.alias.password=password



三、献上脚本

3.1  主逻辑脚本

完整脚本下载地址: http://download.csdn.net/detail/qhexin/7499643

我写了三个脚本,一个是用来 debug 的,一个是用来 release 单个,一个是用来批量打多个渠道的包。按日常使用情况选择不同的脚本来执行。这里我只放批量打包那个。

#!/usr/bin/sh
# @Author:agui
# 本文件的主要作用是快速打 包
# 然后安装到设备上 再启动
echo 'We will start'
echo "This sh file is run for Release all channel !!"


#获取.sh文件的路径
#shFilePath="noPathYet"

cd `dirname $0`
shFilePath=$(pwd)
echo $shFilePath
#cd -


# 创建输出目录.打包后的文件会在这里生成
output_release_filepath="$shFilePath/outputChannelsApk"


rm -rf $output_release_filepath
mkdir $output_release_filepath

# 编译 .so 文件
echo " "
echo " "
echo "----开始编译 .so 文件----"
echo " "
echo " "
echo $shFilePath
cd $shFilePath

sh build_native.sh -j4


# 打包
echo " "
echo " "
echo "----开始部署 打包 所有渠道----"
echo " "
echo " "
ant deployall

# 安装
echo " "
echo " "
adb devices
cd $output_release_filepath

hasRunAApplication="false"

# 遍历文件,全安装起来
for file in $output_release_filepath/*
do
if [ -f "$file" ]
then
echo "Find file="$file
singalFileHouZhui=${file##*.}
echo $singalFileHouZhui

if [ "$singalFileHouZhui" == "apk" ]
then
#安装
echo "Going to install"
echo "Now Call: adb install -r $file"
adb install -r $file

if [ "$hasRunAApplication" == "false" ]
then
echo "try open app"
#启动
adb shell am start -n 你的包名/你的activity名
hasRunAApplication="true"
fi


fi

fi
done




3.2  生成 so 文件脚本 build_native.sh


# options

buildexternalsfromsource=

usage(){
cat << EOF
usage: $0 [options]

Build C/C++ code for $APPNAME using Android NDK

OPTIONS:
-s	Build externals from source
-h	this help
EOF
}

while getopts "sh" OPTION; do
case "$OPTION" in
s)
buildexternalsfromsource=1
;;
h)
usage
exit 0
;;
esac
done

# paths

if [ -z "${NDK_ROOT+aaa}" ];then
echo "please define NDK_ROOT"
exit 1
fi

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths relative to current directory
COCOS2DX_ROOT="$DIR/../../.."
APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"

echo "NDK_ROOT = $NDK_ROOT"
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
echo "APP_ROOT = $APP_ROOT"
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"

# make sure assets is exist
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
    rm -rf "$APP_ANDROID_ROOT"/assets
fi

mkdir "$APP_ANDROID_ROOT"/assets

# copy resources
for file in "$APP_ROOT"/Resources/*
do
if [ -d "$file" ]; then
    cp -rf "$file" "$APP_ANDROID_ROOT"/assets
fi

if [ -f "$file" ]; then
    cp "$file" "$APP_ANDROID_ROOT"/assets
fi
done

# 删除资源文件中音效中的mp3格式和m4a格式,只留下ogg
MusicCleanDir="$APP_ANDROID_ROOT/assets/music/majiangTable/action $APP_ANDROID_ROOT/assets/music/majiangTable/BigFan $APP_ANDROID_ROOT/assets/music/majiangTable/boy $APP_ANDROID_ROOT/assets/music/majiangTable/chipenggangtinghu $APP_ANDROID_ROOT/assets/music/majiangTable/girl $APP_ANDROID_ROOT/assets/music/FlappyBird/effect"
for mDir in $MusicCleanDir
do
echo "clean non-ogg file in $mDir"
rm -f "$mDir"/*.mp3
rm -f "$mDir"/*.m4a
rm -f "$mDir"/*.wav
done

# run ndk-build
if [[ "$buildexternalsfromsource" ]]; then
    echo "Building external dependencies from source"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
else
    echo "Using prebuilt externals"
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
fi


3.3 Ant配置文件 custom_rules.xml  

这个文件需要放置到工程目录下。

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" >

    <taskdef resource="net/sf/antcontrib/antcontrib.properties" >
        <classpath>
            <pathelement location="lib/ant-contrib-1.0b3.jar" />
        </classpath>
    </taskdef>

    <target name="agdebug" >
		<antcall target="onlydebug">
			<param name="channel" value="${main_channel}"/>
        </antcall>        
    </target>
    
    <target name="deploy" >
		<antcall target="modify_manifest_only_offical">
			<param name="channel" value="${main_channel}"/>
        </antcall>        
    </target>

    <target name="deployall" >
        <foreach
            delimiter=","
            list="${all_channels}"
            param="channel"
            target="modify_channels" >
        </foreach>
    </target>
    
    <!-- 多渠道打包 -->
    <target name="modify_channels" >
        <echo level="warning" message="${channel}" />
        <propertyregex property="channelname" input="${channel}" regexp="(.*):" select="\1"/>
   		<propertyregex property="packagename" input="${channel}" regexp=":(.*)" select="\1"/>
        
        <echo level="warning" message="${channelname}" />
        <echo level="warning" message="${packagename}" />
        <echo level="warning" message="Ready to package" />
        
   		<!-- 设置渠道名 -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">
            <regexp pattern="android:name="UMENG_CHANNEL" android:value="(.*)"" />
            <substitution expression="android:name="UMENG_CHANNEL" android:value="${channelname}"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 设置包名  -->
        <replaceregexp  encoding="utf-8" flags="g" byline="false">
            <regexp pattern="package="(.*)"" />
            <substitution expression="package="${packagename}"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 修改 debug=false -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">
            <regexp pattern="android:debuggable="(.*)"" />
            <substitution expression="android:debuggable="false"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 打包 -->
        <property
        name="out.final.file"
        location="outputChannelsApk/${apk_prename}_${channelname}.apk" />
        
        <antcall target="clean" />
        <antcall target="release" />

    </target>
    
    <!-- 主渠道打包 -->
    <target name="modify_manifest_only_offical" >
        <echo level="warning" message="${channel}" />
        <propertyregex property="channelname" input="${channel}" regexp="(.*):" select="\1"/>
   		<propertyregex property="packagename" input="${channel}" regexp=":(.*)" select="\1"/>
        
   		<!-- 设置渠道名  -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">
            <regexp pattern="android:name="UMENG_CHANNEL" android:value="(.*)"" />
            <substitution expression="android:name="UMENG_CHANNEL" android:value="${channelname}"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 设置包名  -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">
            <regexp pattern="package="(.*)"" />
            <substitution expression="package="${packagename}"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 修改 debug=false -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">
            <regexp pattern="android:debuggable="(.*)"" />
            <substitution expression="android:debuggable="false"" />
            <fileset
            dir=""
            includes="AndroidManifest.xml" />
        </replaceregexp>
        
        <!-- 打包 -->
        <property
        name="out.final.file"
        location="outputOfficalApk/${apk_prename}_${channelname}.apk" />
        
        <antcall target="clean" />
        <antcall target="release" />
    </target>
    
    <!-- debug 包 -->
    <target name="onlydebug" >
        <echo level="warning" message="${channel}" />
        <propertyregex property="channelname" input="${channel}" regexp="(.*):" select="\1"/>
   		<propertyregex property="packagename" input="${channel}" regexp=":(.*)" select="\1"/>
       
   		<!-- 设置渠道名  -->
       <replaceregexp encoding="utf-8" flags="g" byline="true">
        <regexp pattern="android:name="UMENG_CHANNEL" android:value="(.*)"" />  
            <substitution expression="android:name="UMENG_CHANNEL" android:value="${channelname}"" />  
           <fileset
                dir=""
                includes="AndroidManifest.xml" />
        </replaceregexp>
        
       <!-- 设置包名  -->
       <replaceregexp encoding="utf-8" flags="g" byline="false">  
        <regexp pattern="package="(.*)"" />  
            <substitution expression="package="${packagename}"" />  
           <fileset
                dir=""
                includes="AndroidManifest.xml" />
        </replaceregexp>
       
       <!-- 修改 debug=false -->
        <replaceregexp encoding="utf-8" flags="g" byline="false">  
        <regexp pattern="android:debuggable="(.*)"" />  
            <substitution expression="android:debuggable="false"" />  
           <fileset
                dir=""
                includes="AndroidManifest.xml" />
        </replaceregexp>
       
       <!-- 打包 -->
        <property
            name="out.final.file"
            location="outputDebugApk/${apk_prename}_${channelname}.apk" />
        
        <antcall target="clean" />
        <antcall target="debug" />
    </target>
    
</project>


四、配置渠道

修改 local.properties 文件。具体按照你的项目来配置吧!

# This file is automatically generated by Android Tools.
# 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 Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/Users/gongzuo-qipai/Documents/tools/androidsdk/adt-bundle-mac-x86_64-20130219/sdk

#main channel ,the format is "channel name : package name"
main_channel=qudaoname:package.package.xxxx

#all channel , the format is "channe name : package name" and other channel ,split with ","
all_channels=qudaoname:package,quandaoname2:package,qudaoname3:package

apk_dir=outputApk

apk_prename=APKNAME




五、运行脚本

如果不需要第一个脚本,那么手动编译C代码,然后再输入 ant  deployall 即可。(不用脚本的话,输出路径要保证有文件夹哦)

用第一个脚本的话,啥都不用改,妥妥的OK拉。







你可能感兴趣的:(Android cocos2d-x 批量打包)