Ant多渠道批量打包帶簽名的包

.打包前的準備工作

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;

    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章