Ant多渠道批量打包带签名的包

来源:互联网 发布:算法导论epub中文版 编辑:程序博客网 时间:2024/05/29 17:22

.打包前的准备工作

1.首先确定你的JDK版本为1.6!

2.从官网http://ant.apache.org/ 下载Ant安装

(1).解压Ant,例如:E:\Ant\apache-ant-1.9.3

(2).我的电脑->属性->高级->环境变量

(3).系统变量新建ANT_HOME,变量值为E:\Ant\apache-ant-1.9.3

(4).系统变量新建或修改path,变量值为%ANT_HOME%\bin

在控制台输入cmd回车, ant 回车

如果出现

Buildfile: build.xml does not exist!

Build failed

这时Ant就安装成功了

3.为了让Ant支持循环打包功能,在Android SDK/tools/lib下放一个扩展的  ant_contrib-1.0b3.jar包。

4.在需要打包的项目中的 AndroidManifest.xml中的Application下添加一个渠道元数据节点。  

 <meta-data android:name="qudao" android:value="channel"/>

 

.build.xml等文件的生成和配置

1.通过终端(cmd)命令自动生成build.xml文件和local.properties两个文件。

android update project -p xxx  (xxx为项目路径)

例如:


执行完成后,Refresh你的项目就会发现项目的根目录下多了两个文件:build.xml和local.properties。

build.xml的内容如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<projectname="IndexActivity"default="release">

 

    <!-- The local.properties fileis created and updated by the 'android' tool.

         It contains the path to theSDK. It should *NOT* be checked into

         Version Control Systems.-->

    <propertyfile="local.properties"/>

 

    <!-- The ant.properties filecan be created by you. It is only edited by the

         'android' tool to addproperties to it.

         This is the place to changesome Ant specific build properties.

         Here are some propertiesyou may want to change/update:

 

         source.dir

             The name of the sourcedirectory. Default is 'src'.

         out.dir

             The name of the outputdirectory. Default is 'bin'.

 

         For other overridableproperties, look at the beginning of the rules

         files in the SDK, attools/ant/build.xml

 

         Properties related to theSDK location or the project target should

         be updated using the'android' tool with the 'update' action.

 

         This file is an integralpart of the build system for your

         application and should bechecked into Version Control Systems.

 

         -->

    <propertyfile="ant.properties"/>

 

    <!-- if sdk.dir was not setfrom one of the property file, then

         get it from theANDROID_HOME env var.

         This must be done before weload project.properties since

         the proguard config can usesdk.dir -->

    <propertyenvironment="env"/>

    <conditionproperty="sdk.dir"value="${env.ANDROID_HOME}">

        <issetproperty="env.ANDROID_HOME"/>

    </condition>

 

    <!-- The project.properties file is created andupdated by the 'android'

         tool, as well as ADT.

 

         This contains projectspecific properties such as project target, and library

         dependencies. Lower levelbuild properties are stored in ant.properties

         (or in .classpath forEclipse projects).

 

         This file is an integralpart of the build system for your

         application and should bechecked into Version Control Systems. -->

    <loadpropertiessrcFile="project.properties"/>

 

    <!-- quick check on sdk.dir-->

    <fail

            message="sdk.dir ismissing. Make sure to generate local.properties using 'android update project'or to inject it through the ANDROID_HOME environment variable."

            unless="sdk.dir"

    />

 

    <!--

        Import per project custombuild rules if present at the root of the project.

        This is the place to putcustom intermediary targets such as:

            -pre-build

            -pre-compile

            -post-compile (This istypically used for code obfuscation.

                           Compiledcode location: ${out.classes.absolute.dir}

                           If thisis not done in place, override ${out.dex.input.absolute.dir})

            -post-package

            -post-build

            -pre-clean

    -->

    <importfile="custom_rules.xml"optional="true"/>

 

    <!-- Import the actual buildfile.

 

         To customize existingtargets, there are two options:

         - Customize only onetarget:

             - copy/paste the targetinto this file, *before* the

               <import> task.

             - customize it to yourneeds.

         - Customize the wholecontent of build.xml

             - copy/paste thecontent of the rules files (minus the top node)

               into this file, replacing the<import> task.

             - customize to yourneeds.

 

         ***********************

         ****** IMPORTANT ******

         ***********************

         In all cases you mustupdate the value of version-tag below to read 'custom' instead of an integer,

         in order to avoid havingyour file be overridden by tools such as "android update project"

    -->

    <!-- version-tag: 1 -->

    <importfile="${sdk.dir}/tools/ant/build.xml"/>

 

</project>

    由生成的build.xml可知:当Ant编译时会先去import一个custom_rules.xml文件,再去import Android中SDK自带的一个build.xml文件

其中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=D:\\Android\\android-sdk

 

2.手动为项目新建一个File,该文件名为ant.properties

创建完成后在ant.properties中添加如下内容

key.store=<keystore>

key.alias=<key>

key.store.password=<keystore pwd>

key.alias.password=<key pwd>

market_channels=xx,yy,zz

app_version=1_0_build_0

 

例如:

key.store=android.keystore

key.alias=android.keystore

key.store.password=123456

key.alias.password=123456

market_channels=anzhuoshichang,jifengshichang

app_version=1_5_qianniu_0

其中:

keystore为签名文件的全路径。

key.alias 生成的keystore别名

key.store.password为私钥库的密码。

key.alias.password为私钥的密码。

market_channels为渠道集合。

app_version为apk的版本

 

生成keystore的方法为,在控制台并在jdk的bin文件下输入以下命令

keytool -genkey -alias android.keystore -keyalg RSA -validity 20000 -keystore android.keystore 

例如

 

其中

-alias android.keystore 生成的keystore别名

-keyalg RSA  加密和数字签名的算法

-validity 20000 有效天数

 

至此,除build.xml和custom_rules.xml外,其余文件配置完成。

三.custom_rules .xml的编写方法:

1.修改生成的build.xml的第二行,修改方法如下:

<projectname="IndexActivity" default="release">

其中name为你项目的名称,default设置为release。

2.循环替换AndroidManifest.xml中qudao的value值并进行自动签名打包,方法如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<projectname="custom_rules">

 

    <property

        name="out.unaligned.dir"

        value="/Users/QianNiuXing_${app_version}/"/>

 

    <mkdirdir="${out.unaligned.dir}"/>

   

    <!-- 打包,并执行ant.release命令,输出到指定目录 -->

 

    <targetname="modify_update_file">

    <echo>*********************** make channel${channel}</echo>

        <replaceregexp

            byline="true"

            encoding="utf-8"

            file="${basedir}\res\values\config.xml">

           <regexppattern="&lt;integername=&quot;origin&quot;>(.*)&lt;/integer>"/>

          <substitutionexpression="&lt;integername=&quot;origin&quot;>${channel}&lt;/integer>"/>

          </replaceregexp>

 

        <property

            name="out.unaligned.file"

            location="${out.unaligned.dir}/QianNiuXing_${app_version}_${channel}.apk"/>

    </target>

    <!-- 开始执行打包,depends中顺序执行,分别是保存AndroidManifest.xml文件,替换,发布,复制,删除 -->

 

    <target

        name="make_one_channels"

        depends="savemanifest,modify_update_file,release,replacemanifest,deletebin"

        description="description">

    </target>

 

    <!-- 事先先保存一份AndroidManifest.xml文件 -->

 

    <targetname="savemanifest">

 

        <copy

            encoding="utf-8"

           file="${basedir}\res\values\config.xml"

            todir="..\temp\build\CONFIG"/>

    </target>

 

    <!-- 删除根目录下的AndroidManifest.xml文件,并将替换后的 AndroidManifest.xml文件拷贝一份至根目录 -->

 

    <targetname="replacemanifest">

 

        <deletefile="${basedir}\res\values\config.xml"/>

 

        <copy

            encoding="utf-8"

            file="..\temp\build\CONFIG\config.xml"

            todir="${basedir}\res\values"/>

    </target>

 

    <!-- 删除根目录下的bin文件,不然只能打包一个渠道 -->

 

    <targetname="deletebin">

 

        <deletedir="${basedir}\bin"/>

    </target>

 

    <!-- 载入 ant-contrib-1.0b3.jar -->

 

    <taskdefresource="net/sf/antcontrib/antcontrib.properties">

 

        <classpath>

 

            <pathelementlocation="E:/Ant/apache-ant-1.9.3/lib/ant-contrib-1.0b3.jar"/>

        </classpath>

    </taskdef>

 

    <!-- ant编译的入口 -->

 

    <targetname="channels">

 

        <!--

           foreach开启循环打包过程

           delimiter:ant.properties中获取到渠道,并用","隔开

           market_channels指的是需要发布的渠道号

           并开始执行make_one_channels

        -->

 

        <foreach

            delimiter=","

            list="${market_channels}"

            param="channel"

            target="make_one_channels">

        </foreach>

    </target>

 

</project>

其中:

1.out.unaligned.dir的value值为apk输出文件夹的绝对路径,文件夹采用QianNiu结合app_version命名,app_version为ant.properties中的app_version

2.out.unaligned.file的location为apk最终的输出路径,apk命名采用QianNiu加app_version加当前的channel加android方式

3.打包的过程:

(1)channels的target是ant的入口,该target中使用foreach循环调用名为make_one_channels的target并把market_channels集合中的每个值通过正则替换给channel

(2)make_one_channels的target指定了每次打包的过程:

   savemanifest:打包前先将原始的AndroidManifest.xml复制到与项目同一层级目录下的temp下build下META-INF中

   modify_update_file:匹配到AndroidManifest.xml中的channel并将其替换

   release:自动编译加签名

   replacemanifest:删除AndroidManifest.xml,将temp/build/META-INF中的原始AndroidManifest.xml复制回项目根目录下

   deletebin:删除bin文件(注:这步很重要,否则只能打出一个渠道的APK,当时做这块的时候碰到的问题)

4.其中末尾taskdef标签下的classpath是ant-contrib-1.0b3.jar的绝对路径

 在项目中我自己是这样做的,因为渠道号我放在了一个文件中congig.xml中,直接通过R.integer.origin来引用的,所以直接改变congig.xml中的值即可:

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


    <property
        name="out.unaligned.dir"
        value="/Apks/${channel}/" />


    <mkdir dir="${out.unaligned.dir}" />


    <!-- 开始执行打包,depends中顺序执行,分别是保存AndroidManifest.xml文件,替换,发布,复制,删除 -->


    <target
        name="make_one_channels"
        depends="deletebin,savemanifest,modify_update_file,release,replacemanifest"
        description="description" >
    </target>


   <!-- 删除根目录下的bin文件,不然只能打包一个渠道 -->
    <target name="deletebin" >
        <delete dir="${basedir}\bin" />
    </target>
    
    <!-- 事先先保存一份config.xml文件 -->
    <target name="savemanifest" >
        <copy
            encoding="utf-8"
file="${basedir}\res\values\config.xml"
            todir="..\temp\build\CONFIG" />
    </target>
    
    <!-- 修改config.xml文件 -->
    <target name="modify_update_file" >
<echo>*********************** make channel ${channel}</echo>
        <replaceregexp
            byline="true"
            encoding="utf-8"
            file="${basedir}\res\values\config.xml">
           <regexp pattern="&lt;integer name=&quot;origin&quot;>(.*)&lt;/integer>"/>
  <substitution expression="&lt;integer name=&quot;origin&quot;>${channel}&lt;/integer>"/>
  </replaceregexp>
        <property
            name="out.unaligned.file"
            location="${out.unaligned.dir}/QianNiuXing_${app_version}_${channel}.apk" />
    </target>
    
    <!-- 打包,并执行ant.release命令,输出到指定目录 -->
    
    <!-- 删除根目录下的config.xml文件,并将替换后的 config.xml文件拷贝一份至根目录 -->
    <target name="replacemanifest" >
        <delete file="${basedir}\res\values\config.xml" />
        <copy
            encoding="utf-8"
            file="..\temp\build\CONFIG\config.xml"
            todir="${basedir}\res\values" />
    </target>


    <!-- 载入 ant-contrib-1.0b3.jar包 -->
    <taskdef resource="net/sf/antcontrib/antcontrib.properties" >
        <classpath>
            <pathelement location="${contrib}" />
        </classpath>
    </taskdef>


    <!-- ant编译的入口 -->
    <target name="channels" >
        <!--
   foreach开启循环打包过程
delimiter:从ant.properties中获取到渠道,并用","隔开
market_channels指的是需要发布的渠道号
并开始执行make_one_channels
        -->
        <foreach
            delimiter=","
            list="${market_channels}"
            param="channel"
            target="make_one_channels" >
        </foreach>
    </target>
</project>


四.打包方法的使用

打开终端(cmd),执行:

注意:打包时,最好从svn上取一份新代码出来,或者clean以下,删除bin文件

antmake_channels

此时,打包开始进行,当出现BUILD SUCCESSFUL代表打包成功!如下图所示:

 

输出的文件夹中多了2APK



 注:1.每次打包前一定要删除掉temp/build/META-INF中的AndroidManifest.xml,特别是在给不同项目做打包时

   2.打包前请检查AndroidManifest.xml中qudao的value值是否为channel,特别是打包失败后再次重新打包的时候一定要将value值改为channel

   3.如果打包时出现Cannot recover key错误导致BUILD FAILD的话,请检查ant.properties中key.alias.password的值后面是否有多余的空格!有的话请把空格删除掉!

 

五.在代码中获取渠道值:

从AndroidManifest.xml中获取

public static int getVersionQuDao(Context context){

        int qudao = 0;

        try{

            ApplicationInfo appInfo =context.getPackageManager().getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA);

            qudao = toInteger(appInfo.metaData.getString("qudao"));

        }catch(NameNotFoundException e){

            e.printStackTrace();

        }

        return qudao;

    }

0 0
原创粉丝点击