zoukankan      html  css  js  c++  java
  • Android项目使用Ant多渠道打包(最新sdk)

    参考文章:

    http://blog.csdn.net/liuhe688/article/details/6679879

    http://www.eoeandroid.com/thread-323111-1-1.html

    http://yangguangfu.iteye.com/blog/723182

    http://blog.csdn.net/cen616899547/article/details/22225947

    一、Android使用Ant的打包流程

      使用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

       

    二、Ant的下载安装

      1、下载:

        从阿帕奇的Ant官网(http://ant.apache.org/ )中,找到download,下载apache-ant-1.9.4-bin.zip。(这里使用的ant不是sdk自带的ant)。

      2、安装及环境变量配置:

        1) 解压Ant,比如解压到D:softwareapache-ant-1.9.4

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

        3) 系统变量新建ANT_HOME,变量值为D:softwareapache-ant-1.9.4

        4)系统变量新建或修改path,变量值为%ANT_HOME%in

        安装好环境变量后,在控制台输入cmd,回车后输入ant -version,如果安装成功会出现相应的ant版本号。

        

    三、下载支持文件:

      一、下载ant-contrib-1.0b3:

        点击链接下载ant-contrib-1.0b3.jar。下载解压后将文件:ant-contrib-1.0b3.jar放入刚安装的ant目录下的bin文件夹中。(也可自行网上下载,然后放入bin目录下)。

      二、下载apkbuilder.bat:

        点击链接下载apkbuilder.bat。下载解压后将文件:apkbuilder.bat放入Android的sdk目录下的tools文件夹中。(也可网上自行下载,然后放入tools目录中)。

    四、签名文件的生成:

      1)输入cmd,打开控制台后,进入安装的jdk的bin下。如:cd D:softwareJavajdk1.7.0_71in。

      2)输入命令:keytool -genkey -v -keystore volley.keystore -alias app -keyalg RSA -validity 20000

        解释:

          -keystore 后面跟的是要生成的签名文件的名称。这里是volley.keystore

          -alias 后面跟的是签名文件的别名。这里是app
          -keyalg 是加密方式。这里是RSA
          -validity 是有效期。这里是20000
      3)回车后,需要连续两次输入密钥库口令。这个口令就是签名文件的密钥的密码要记住这个密码,待会会用到。(这里我用的是654321)

      4)接下来根据提示输入一些基本信息,然后回复y。就会自动生成签名文件。

      5)接下来会提示输入别名的密钥口令。可以直接回车,与签名文件的密钥库口令一样,也可以再输入一个密码。这个密码也要记住,待会会用到(这里我用的是123456)

      6)这样就生成好了签名文件,签名文件在jdk的bin目录下。(我这里是volley.keystore)。

      

    五、在工程中生成build.xml文件:

      1)工程目录结构:

      直接在工程目录中新建build.xml文件。

      

      2)将jdk中bin目录下刚生成的签名文件volley.keystore放入工程目录中。

      3)编辑build.xml文件

    <project name="Test" default="release" basedir=".">
        <!-- 环境变量 -->
        <property environment="env" />
        <!-- 使用第三方的ant包,使ant支持for循环-->
        <taskdef resource="net/sf/antcontrib/antcontrib.properties">
            <classpath>
                <!-- 修改一:将ant下的路径改为绝对路径。也可以用"${env.ANT_HOME}/lib/ant-contrib-1.0b3.jar",不过我在这里老是找不到,所以就用绝对路径了 -->
                <pathelement location="D:/software/apache-ant-1.9.4/lib/ant-contrib-1.0b3.jar" />
            </classpath>
        </taskdef>
        <!-- 应用名称 -->
        <property name="appName" value="${ant.project.name}" />
        <!--  修改二:SDK目录的路径 ,也可以用"${env.ANDROID_SDK_HOME}",不过我还是找不到,也改成绝对路径了-->
        <property name="sdk-folder" value="D:softwareSDK-20140702sdk" />
        <!-- 修改三:SDK指定平台目录为platforms/android-20-->
        <property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-20" />
        <!-- SDK中tools目录 -->
        <property name="sdk-tools" value="${sdk-folder}/tools" />
        <!-- SDK指定平台中tools目录 -->
        <property name="sdk-platform-tools" value="${sdk-folder}/platform-tools" />
        
        <!-- 修改四:SDK指定平台中build-tools目录为 build-tools/android-4.4W-->
        <property name="sdk-build-tools" value="${sdk-folder}/build-tools/android-4.4W" />
    
        <!-- 使用到的命令(当前系统为windows,如果系统为linux,可将.bat文件替换成相对应的命令) -->
        <property name="aapt" value="${sdk-build-tools}/aapt" />
        <property name="aidl" value="${sdk-build-tools}/aidl" />
        <property name="dx" value="${sdk-build-tools}/dx.bat" />
        <!-- 修改五:将下载好的apkbuilder.bat文件放入${sdk-folder}/tools目录下 -->
        <property name="apkbuilder" value="${sdk-tools}/apkbuilder.bat" />
        <!-- 修改六:如果报错,就将jdk的路径改为绝对路径 -->
        <property name="jarsigner" value="${env.JAVA_HOME}/bin/jarsigner" />
        <property name="zipalign" value="${sdk-build-tools}/zipalign.exe" />
    
        <!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar -->
        <property name="android-jar" value="${sdk-platform-folder}/android.jar" />
        <property name="android-maps-jar" value="${sdk-folder}/add-ons/addon_google_apis_google_inc_8/libs/maps.jar" />
    
        <!--渠道 -->
        <property name="channelname" value="" />
        <property name="channelkey" value="" />
        <!-- 渠道名:渠道号 -->
        <property name="key" value="UM:aaaaaa,BAI:bbbb" />
        
        <!-- 编译aidl文件所需的预处理框架文件framework.aidl -->
        <property name="framework-aidl" value="${sdk-platform-folder}/framework.aidl" />
        <!-- 清单文件 -->
        <property name="manifest-xml" value="AndroidManifest.xml" />
        <!-- 源文件目录 -->
        <property name="resource-dir" value="res" />
        <property name="asset-dir" value="assets" />
        <!-- java源文件目录 -->
        <property name="srcdir" value="src" />
        <property name="srcdir-ospath" value="${basedir}/${srcdir}" />
        
        <!-- 外部类库所在目录 -->
        <property name="external-lib" value="libs" />
        <property name="external-lib-ospath" value="${basedir}/${external-lib}" />
    
        <!-- 修改七:修改版本号 -->
        <property name="version" value="1.0" />
        
        <!--循环打包 -->
            <target name="deploy">
                <foreach target="modify_manifest" list="${key}" param="nameandchannel" delimiter=",">
                </foreach>
            </target>
            <target name="modify_manifest">
                <!-- 获取渠道名字 -->
                <propertyregex override="true" property="channelname" input="${nameandchannel}" regexp="(.*):" select="1" />
                <!-- 获取渠道号码 -->
                <propertyregex override="true" property="channelkey" input="${nameandchannel}" regexp=":(.*)" select="1" />
                <!-- 正则匹配替换渠道号 -->
                <replaceregexp flags="g" byline="false" encoding="UTF-8">
                    <regexp pattern='meta-data android:value="(.*)" android:name="app_key"' />
                    <substitution expression='meta-data android:value="${channelkey}" android:name="app_key"' />
                    <fileset dir="" includes="AndroidManifest.xml" />
                </replaceregexp>
                <antcall target="zipalign" />
            </target>
        
        <!-- 初始化工作 -->
        <target name="init">
            <echo>目录初始化....</echo>
            <!-- 生成R文件的相对目录 -->
            <var name="outdir-gen" value="gen" />
            <!-- 编译后的文件放置目录 -->
            <var name="outdir-bin" value="bin-${channelname}" />
            <!-- 生成class目录 -->
            <var name="outdir-classes" value="${outdir-bin}" />
            <var name="outdir-classes-ospath" value="${basedir}/${outdir-classes}" />
    
            <!-- classes.dex相关变量 -->
            <var name="dex-file" value="classes.dex" />
            <var name="dex-path" value="${outdir-bin}/${dex-file}" />
            <var name="dex-ospath" value="${basedir}/${dex-path}" />
    
            <!-- 经过aapt生成的资源包文件 -->
            <var name="resources-package" value="${outdir-bin}/resources.ap_" />
            <var name="resources-package-ospath" value="${basedir}/${resources-package}" />
    
            <!-- 未认证apk包 -->
            <var name="out-unsigned-package" value="${outdir-bin}/${appName}-unsigned.apk" />
            <var name="out-unsigned-package-ospath" value="${basedir}/${out-unsigned-package}" />
    
            <!-- 修改八:修改对应的签名文件的文件名 -->
            <var name="keystore-file" value="${basedir}/volley.keystore" />
    
            <!-- 已认证apk包 -->
            <var name="out-signed-package" value="${outdir-bin}/${appName}-${channelname}-${version}.apk" />
            <var name="out-signed-package-ospath" value="${basedir}/${out-signed-package}" />
            <delete dir="${outdir-bin}" />
            <mkdir dir="${outdir-bin}" />
            <mkdir dir="${outdir-classes}" />
        </target>
    
        <!-- 根据工程中的资源文件生成R.java文件  -->
        <target name="gen-R" depends="init">
            <echo>生成R.java文件....</echo>
            <exec executable="${aapt}" failonerror="true">
                <arg value="package" />
                <arg value="-f" />
                <arg value="-m" />
                <arg value="-J" />
                <arg value="${outdir-gen}" />
                <arg value="-S" />
                <arg value="${resource-dir}" />
                <arg value="-M" />
                <arg value="${manifest-xml}" />
                <arg value="-I" />
                <arg value="${android-jar}" />
            </exec>
        </target>
    
        <!-- 编译aidl文件 -->
        <target name="aidl" depends="gen-R">
            <echo>编译aidl文件....</echo>
            <apply executable="${aidl}" failonerror="true">
                <!-- 指定预处理文件 -->
                <arg value="-p${framework-aidl}" />
                <!-- aidl声明的目录 -->
                <arg value="-I${srcdir}" />
                <!-- 目标文件目录 -->
                <arg value="-o${outdir-gen}" />
                <!-- 指定哪些文件需要编译 -->
                <fileset dir="${srcdir}">
                    <include name="**/*.aidl" />
                </fileset>
            </apply>
        </target>
    
        <!-- 将工程中的java源文件编译成class文件 -->
        <target name="compile" depends="aidl">
            <echo>java源文件编译成class文件....</echo>
            <javac encoding="utf-8" target="1.5" srcdir="." destdir="${outdir-classes}" bootclasspath="${android-jar}" verbose="false">
                <compilerarg line="-encoding GBK " />
                <classpath>
                    <fileset dir="${external-lib}" includes="*.jar" />
                </classpath>
            </javac>
        </target>
    
    
        <!-- 将.class文件转化成.dex文件 -->
        <target name="dex" depends="compile">
            <echo>将.class文件转化成.dex文件....</echo>
            <exec executable="${dx}" failonerror="true">
                <arg value="--dex" />
                <!-- 输出文件 -->
                <arg value="--output=${dex-ospath}" />
                <!-- 要生成.dex文件的源classes和libraries -->
                <arg value="${outdir-classes-ospath}" />
                <arg value="${external-lib-ospath}" />
            </exec>
        </target>
    
        <!-- 将资源文件放进输出目录 -->
        <target name="package-res-and-assets">
            <echo>将资源文件放进输出目录....</echo>
            <exec executable="${aapt}" failonerror="true">
                <arg value="package" />
                <arg value="-f" />
                <arg value="-M" />
                <arg value="${manifest-xml}" />
                <arg value="-S" />
                <arg value="${resource-dir}" />
                <arg value="-A" />
                <arg value="${asset-dir}" />
                <arg value="-I" />
                <arg value="${android-jar}" />
                <arg value="-F" />
                <arg value="${resources-package}" />
            </exec>
        </target>
    
        <!-- 打包成未签证的apk -->
        <target name="package" depends="dex, package-res-and-assets">
            <echo>打包成未签证的apk....</echo>
            <exec executable="${apkbuilder}" failonerror="true">
                <arg value="${out-unsigned-package-ospath}" />
                <arg value="-u" />
                <arg value="-z" />
                <arg value="${resources-package-ospath}" />
                <arg value="-f" />
                <arg value="${dex-ospath}" />
                <arg value="-rf" />
                <arg value="${srcdir-ospath}" />
            </exec>
        </target>
    
        <!-- 对apk进行签证 -->
        <target name="jarsigner" depends="package">
            <echo>Packaging signed apk for release...</echo>
            <exec executable="${jarsigner}" failonerror="true">
                <!-- 修改九:如果JDK大于7,需要将下面五行代码保留,如果是6,就可以不需要(保留应该也没问题吧,还没试),否则,最终的APK安装会出现“该文件签名有问题,无法安装” -->
                <arg value="-verbose" />
                <arg value="-digestalg" />
                <arg value="SHA1" />
                <arg value="-sigalg" />
                <arg value="MD5withRSA" />
                
                
                <arg value="-keystore" />
                <arg value="${keystore-file}" />
                <arg value="-storepass" />
                <!-- 修改十:以下密码替换成你签名文件密钥的密码 -->
                <arg value="654321" />
                <arg value="-keypass" />
                <!-- 修改十一:以下密码替换成你签名文件别名的密码 -->
                <arg value="123456" />
                <arg value="-signedjar" />
                <arg value="${out-signed-package-ospath}" />
                <arg value="${out-unsigned-package-ospath}" />
                <!-- 修改十二:签名文件的别名 -->
                <arg value="app" />
            </exec>
        </target>
    
        <!-- 发布 -->
        <target name="release" depends="jarsigner">
            <!-- 删除未签证apk -->
            <delete file="${out-unsigned-package-ospath}" />
            <echo>APK is released. path:${out-signed-package-ospath}</echo>
        </target>
        <!-- 打包的应用程序进行优化 -->
        
        <target name="zipalign" depends="release">
            <exec executable="${zipalign}" failonerror="true">
                <arg value="-v" />
                <arg value="4" />
                <arg value="${out-signed-package-ospath}" />
                <arg value="${out-signed-package-ospath}-zipaligned.apk" />
            </exec>
        </target>
    </project>

      详解:

       修改一:将ant下的路径改为绝对路径。也可以用"${env.ANT_HOME}/lib/ant-contrib-1.0b3.jar",不过我在这里老是找不到,所以就用绝对路径了。(这里使用ANT_HOME,前提是在环境变量中有做相应的配置)

    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
            <classpath>
                <!-- 修改一:将ant下的路径改为绝对路径。也可以用"${env.ANT_HOME}/lib/ant-contrib-1.0b3.jar",不过我在这里老是找不到,所以就用绝对路径了 -->
                <pathelement location="D:/software/apache-ant-1.9.4/lib/ant-contrib-1.0b3.jar" />
            </classpath>
        </taskdef>

      修改二:SDK目录的路径 ,也可以用"${env.ANDROID_SDK_HOME}",不过我还是找不到,也改成绝对路径了。(这里使用ANDROID_SDK_HOME,前提是在环境变量中有做相应的配置)

    <property name="sdk-folder" value="D:softwareSDK-20140702sdk" />

      修改三:SDK指定平台目录为platforms/android-20

    <property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-20" />

      修改四:SDK指定平台中build-tools目录为 build-tools/android-4.4W

    <property name="sdk-build-tools" value="${sdk-folder}/build-tools/android-4.4W" />

      修改五:将下载好的apkbuilder.bat文件放入${sdk-folder}/tools目录下

    <property name="apkbuilder" value="${sdk-tools}/apkbuilder.bat" />

      修改六:如果报错,就将jdk的路径改为绝对路径

    <property name="jarsigner" value="${env.JAVA_HOME}/bin/jarsigner" />

      修改七:修改版本号

    <property name="version" value="1.0" />

      修改八:修改对应的签名文件的文件名

    <var name="keystore-file" value="${basedir}/volley.keystore" />

      修改九:如果JDK大于7,需要将下面五行代码保留,如果是6,就可以不需要(保留应该也没问题吧,还没试),否则,最终的APK安装会出现“该文件签名有问题,无法安装”

      修改十:以下密码替换成你签名文件密钥的密码

      修改十一:以下密码替换成你签名文件别名的密码

      修改十二:签名文件的别名

    <!-- 对apk进行签证 -->
        <target name="jarsigner" depends="package">
            <echo>Packaging signed apk for release...</echo>
            <exec executable="${jarsigner}" failonerror="true">
                <!-- 修改九:如果JDK大于7,需要将下面五行代码保留,如果是6,就可以不需要(保留应该也没问题吧,还没试),否则,最终的APK安装会出现“该文件签名有问题,无法安装” -->
                <arg value="-verbose" />
                <arg value="-digestalg" />
                <arg value="SHA1" />
                <arg value="-sigalg" />
                <arg value="MD5withRSA" />
                
                
                <arg value="-keystore" />
                <arg value="${keystore-file}" />
                <arg value="-storepass" />
                <!-- 修改十:以下密码替换成你签名文件密钥的密码 -->
                <arg value="654321" />
                <arg value="-keypass" />
                <!-- 修改十一:以下密码替换成你签名文件别名的密码 -->
                <arg value="123456" />
                <arg value="-signedjar" />
                <arg value="${out-signed-package-ospath}" />
                <arg value="${out-unsigned-package-ospath}" />
                <!-- 修改十二:签名文件的别名 -->
                <arg value="app" />
            </exec>
        </target>

      

       循环打包:

      1)在这句话里面循环:

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

      2)在modify_manifest里,将 ${key}对应的值(也就是前面定义的<property name="key" value="UM:aaaaaa,BAI:bbbb" />) 按照delimiter="," 来分隔,进行分别打包。

    <target name="modify_manifest">
                <!-- 获取渠道名字 -->
                <propertyregex override="true" property="channelname" input="${nameandchannel}" regexp="(.*):" select="1" />
                <!-- 获取渠道号码 -->
                <propertyregex override="true" property="channelkey" input="${nameandchannel}" regexp=":(.*)" select="1" />
                <!-- 正则匹配替换渠道号 -->
                <replaceregexp flags="g" byline="false" encoding="UTF-8">
                    <regexp pattern='meta-data android:value="(.*)" android:name="app_key"' />
                    <substitution expression='meta-data android:value="${channelkey}" android:name="app_key"' />
                    <fileset dir="" includes="AndroidManifest.xml" />
                </replaceregexp>
                <antcall target="zipalign" />
            </target>

    六、运行:

      1)打开ant

      2)选中deploy,去掉选中release[default],点击运行

      

      提示:Android官网下载的adt连带Eclipse和sdk。查看过sdk后发现有ant插件,但是在eclipse中的showview没有相应的插件界面。所以我就下载了一个纯版的Eclipse再安装sdk,这样就有ant插件了,不知道有没有更好的方法,看起来这样解决笨笨的。

    七、常见异常:

      1)ant的路径配置不对

      2)sdk路径配置不对

      完

  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/sonyi/p/4151053.html
Copyright © 2011-2022 走看看