Android apk ant打包

apk打包流程

打包流程

以上图就是整个apk打包的流程.


具体流程可以分为8步:
1. 通过aapt工具将 资源文件(res)、清单文件(AndroidManifest.xml)生成对应的R.java文件.
2. 通过aidl工具 将 aidl文件转化为java文件.
3. 通过javac工具,将.java文件转化为.class文件.
4. 将libs下的jar解压到输出目录中.
5. 通过dex命令 将class文件转换为dex文件.
6. 通过aapt工具生成资源文件包.
7. 生成未签名的apk安装文件.
8. 生成签名的apk安装文件.


以上流程不管是命令行打包还是ant打包, 都是不变的,下面我们来说一下完整的ant打包.

ant使用

  1. ant环境变量的配置.
    首先下载http://ant.apache.org/bindownload.cgi.
    和jdk一样配置ANT_HOME ,在PATH中添加ANT_HOME目录下的bin目录
  2. 测试.
    在CMD命令行中输入ant -version, 显示ant版本则说明配置成功.
  3. 使用

    • ant脚本命名必须是build.xml,当然你可以不这样命名,但是这样是有好处的.
    • 如何运行ant脚本: 在当前目录运行ant命令即可(已配好环境变量)
    • 语法
      首先, 我们先来看以下代码:

      <?xml version="1.0" encoding="UTF-8"?>
      <!-- <!DOCTYPE project SYSTEM "ant.dtd" > -->
      <!-- project根标签:代表项目; basedir属性:项目根目录; default:默认执行的任务 -->
      <!-- target:任务标签,每一个任务指令都需要一个target -->
      <!-- mkdir:创建目录标签 -->
      <!-- echo:打印标签,打印的内容由message属性指定 -->
      
      <project name="MyProject" default="printMessage">
      
      
          <!-- 获取环境变量 -->
          <property environment="env"/>
          <!-- build所在目录 -->
          <property name="buildDir" location="${basedir}/build"/>
      
          <!-- 打印JAVA_HOME任务 -->
          <target name="printJavaHome">
              <echo message="${env.JAVA_HOME}"/>
          </target>
      
          <!-- depends:指定任务执行顺序,依赖关系 -->
          <target name="printMessage" depends="printJavaHome">
      
              <echo message="Hello ant"/>
          </target>
      
          <target name="mkBuildDir">
              <mkdir dir="${buildDir}"/>
          </target>
      
          <target name="mkClassesDir">
              <mkdir dir="${buildDir}/classes"/>
          </target>
      
           <target name="mkBinDir">
              <mkdir dir="${buildDir}/bin"/>
          </target>
      
           <!-- 初始化任务:创建目录 -->
           <target name="init" depends="mkClassesDir,mkBinDir"/>
      
          <!-- 删除目录 -->
          <target name="deleteBuildDir">
              <delete dir="${buildDir}"/>
          </target>
      
      </project>
      

      注意:以上代码不具有任何参考价值, 仅作解释ant标签以及语法的使用,请勿深究.
      不知道你是不是已经看出有一个符号

      ${名称}

      没错,这就是一个引用.

  4. 相信你对ant的基本的语法已经有了一定的了解, 那么, 只要使用这样的语法按照以下的命令格式就可以打包一个apk了.

具体打包命令

  1. 首先你有一个未打包的完整的项目(没有bin目录等), 在项目的根目录下新建 gen目录(参考eclipse),并且依次在gen目录下新建清单文件总包名对应的文件目录

    例如: 清单文件中包名是org.example.android,那么就在gen目录中新建目录结构为 gen/org/example/android

  2. 通过命令生成R.java

    aapt package -f -m -J [R文件目录(gen)] -S [资源文件目录(res)] -I [android环境jar(android.jar)] -M [清单文件(AndroidManifest.xml)]

    []的参数都是可选参数。
    [-d]: 指定一个或多个设备的资源文件被添加,多个资源文件用逗号隔开__
    [-f]: 是否覆盖已经存在的文件(添加此参数即为覆盖,否则不覆盖)__
    [-m]: 打包资源的文件目录,目录地址是-J参数指定__
    [-J]: 指定R文件生成的目录__
    [-S]: 需要打包的资源文件目录__
    [-I]: 指定环境android.jar的文件目录__
    [-M]: 清单文件的路径__

  3. 通过aidl工具 将 aidl文件转化为java文件

    aidl -I[项目的源文件目录(src)] -p[aidl框架环境文件(framework.aidl)] -o[aidl输出目录(gen)] [要转换的aidl文件(your.aidl)]

  4. 通过javac工具,将.java文件转化为.class文件

    javac -encoding [编码(gbk or utf-8)] -target [版本(1.6 or 1.7)] -bootclasspath [android环境jar(android.jar)] -cp [依赖的jar(多个用;隔开;结尾)] -d [class文件输出目录] [要编译的java文件(多个用空格分开)]

  5. 将libs下的jar解压到输出目录中

    jar xvf [jar文件]

  6. 通过dex命令 将class文件转换为dex文件

    dx.bat –dex –output=[全路径的输出文件(classes.dex)] [全路径的class文件对应的目录]

    [全路径的class文件对应的目录] : 如果此目录依赖了其他的jar文件,需要用 |分隔开
    命令: dex.bat –dex –output=输出路径 需要转换的class文件对应的路径

  7. 通过aapt工具生成资源文件包

    aapt package -f -M [清单文件(AndroidManifest.xml)] -S [资源文件目录(res)] -A [资产文件目录(assets)] -I [android环境jar(android.jar)] -F [输出的文件(resoures.ap_)]

  8. 生成未签名的apk安装文件

    apkbuilder [输出的全路径apk] -u -z [全路径打包好的资源文件包] -f [全路径dex文件] -rf [全路径的src目录] -rj [全路径的libs目录]

  9. 生成签名的apk安装文件

    • 生成签名文件

    keytool -genkeypair -alias “itheima” -validity 365 -keyalg “RSA” -keystore itheima.keystore

    -alias : 签名的别名 -validity : 签名的时效 -keyalg : 加密的算法 -keystore : 生成的签名路径

    • 通过签名文件给apk文件进行签名

    jarsigner -keystore 签名文件 -storepass 签名文件的密码 -keypass 签名密码 -signedjar 生成的签名文件 未签名的文件 签名的别名

以下为参考代码,注意,代码本身没有任何参考意义,仅作帮助理解ant的使用

<?xml version="1.0" encoding="UTF-8"?>
<!-- <!DOCTYPE project SYSTEM "ant.dtd" > -->
<project name="MyProject" default="signedApk">

    <!-- gen目录 -->
    <property name="genDir" location="${basedir}/gen"/>

    <!-- build目录 -->
    <property name="buildDir" location="${basedir}/build"/>
    <property name="classesDir" location="${basedir}/build/classes"/>
     <!-- res目录 -->
    <property name="resDir" location="${basedir}/res"/>
     <!-- src目录 -->
    <property name="srcDir" location="${basedir}/src"/>
     <!-- android.jar目录 -->
    <property name="androidJar" location="E:\AndroidSdk\platforms\android-19\android.jar"/>
      <!-- 清单文件目录 -->
    <property name="mainfestDir" location="${basedir}/AndroidManifest.xml"/>
    <!-- framework.aidl所在目录 -->
    <property name="frameworkAidlDir" location="E:\AndroidSdk\platforms\android-19\framework.aidl"/>

     <target name="deleteDir">
        <delete dir="${genDir}"/>
        <delete dir="${buildDir}"/>
    </target>

    <!-- 任务:初始化-删除目录、创建目录 -->
    <!-- 任务:创建gen目录 -->
    <target name="mkGenDir" depends="deleteDir">
        <mkdir dir="${genDir}"/>
        <mkdir dir="${buildDir}"/>
        <mkdir dir="${classesDir}"/>
    </target>


    <!-- aapt命令 -->
    <property name="aapt" location="E:\AndroidSdk\platform-tools\aapt.exe"/>
    <!-- aidl命令 -->
    <property name="aidl" location="E:\AndroidSdk\platform-tools\aidl.exe"/>
    <!-- 任务:生成R文件 -->
    <!-- aapt package -f -m -J gen -S res -I E:\AndroidSdk\platforms\android-19\android.jar -M Android
Manifest.xml -->

    <target name="genR" depends="mkGenDir">
        <exec executable="${aapt}">
            <arg value="p"/>
            <arg value="-f"/>
            <arg value="-m"/>
            <arg value="-J"/>
            <arg value="${genDir}"/>
            <arg value="-S"/>
            <arg value="${resDir}"/>
            <arg value="-I"/>
            <arg value="${androidJar}"/>
            <arg value="-M"/>
            <arg value="${mainfestDir}"/>
        </exec>
    </target>


    <!-- aidl生成java -->
    <!-- aidl -Isrc -pE:\AndroidSdk\platforms\android-19\framework.aidl -ogen src\com\android\internal
\telephony\ITelephony.aidl -->
    <target name="aidlCompile" depends="genR">
        <apply executable="${aidl}">
            <arg value="-I${srcDir}"/>
            <arg value="-p${frameworkAidlDir}"/>
            <arg value="-o${genDir}"/>
            <!-- 指定aidl文件所在目录,所有aidl文件-->
            <fileset dir="${srcDir}" includes="**/*.aidl"/>
        </apply>
    </target>

    <!-- 任务:java编译成class -->
    <!-- javac -encoding [编码(gbk or utf-8)] -target [版本(1.6 or 1.7)] 
    -bootclasspath [android环境jar(android.jar)] -cp [依赖的jar(多个用;隔开;结尾)] 
    -d [class文件输出目录] [要编译的java文件(多个用空格分开)] -->

    <property name="libsDir" location="${basedir}/libs"></property>

    <target name="javaCompile" depends="aidlCompile">
        <javac encoding="utf-8" bootclasspath="${androidJar}" destdir="${classesDir}">
             <classpath>
                    <!-- 指定libs目录下所有jar包 -->
                    <fileset includes="**/*.jar" dir="${libsDir}"/>
            </classpath>
            <!-- java文件所在目录,src和gen -->
            <src path="${srcDir}"/>
            <src path="${genDir}"/>
        </javac>
    </target>

    <!-- 解压libs下所有jar包 -->
    <target name="unJar" depends="javaCompile">
        <!-- unjar标签:解压 ,dest属性表示解压的目录-->
        <unjar dest="${classesDir}">
            <fileset includes="**/*.jar" dir="${libsDir}"/>
        </unjar>
    </target>

    <!-- dx.bat命令 -->
    <property name="dx" location="E:\AndroidSdk\build-tools\23.0.3\dx.bat"/>
    <!-- classes.dex 目录-->
    <property name="dexDir" location="${buildDir}/classes.dex"/>
    <target name="dexCompile" depends="unJar">
        <exec executable="${dx}">
            <arg value="--dex"/>
            <arg value="--output=${dexDir}"/>
            <arg value="${classesDir}"/>
        </exec>
    </target>

    <!-- 资产目录 -->
    <property name="assetDir" location="${basedir}/assets"/>
    <!-- resources.ap_所在目录 -->
    <property name="resourcesApDir" location="${buildDir}/resources.ap_"/>
    <!-- 任务:打包资源文件resources.ap_ -->
    <target name="resourcesCompile" depends="dexCompile">
        <exec executable="${aapt}">
            <arg value="p"/>
            <arg value="-f"/>
            <arg value="-M"/>
            <arg value="${mainfestDir}"/>
            <arg value="-S"/>
            <arg value="${resDir}"/>
            <arg value="-A"/>
            <arg value="${assetDir}"/>
            <arg value="-I"/>
            <arg value="${androidJar}"/>
            <arg value="-F"/>
            <arg value="${resourcesApDir}"/>
        </exec>
    </target>
    <!-- apkbuilder命令 -->
    <property name="apkbuilder" location="E:\AndroidSdk\tools\apkbuilder.bat"/>
    <!-- 未签名apk目录 -->
    <property name="unsignedApkDir" location="${buildDir}/MykeySave_unsigned.apk"/>
    <!-- apkbuilder [输出的全路径apk] -u -z [全路径打包好的资源文件包] -f [全路径dex文件]  -rf  [全路径的src目录]  -rj  [全路径的libs目录]  -->
    <target name="unsignedApk" depends="resourcesCompile">
        <exec executable="${apkbuilder}">
            <arg value="${unsignedApkDir}"/>
            <arg value="-u"/>
            <arg value="-z"/>
            <arg value="${resourcesApDir}"/>
            <arg value="-f"/>
            <arg value="${dexDir}"/>
            <arg value="-rf"/>
            <arg value="${srcDir}"/>
             <arg value="-rj"/>
            <arg value="${libsDir}"/>
        </exec>
    </target>

    <!-- 签名apk -->
    <property name="signedApkDir" location="${buildDir}/MykeySave_signed.apk"/>
    <property environment="evn"/>
    <!-- jarsigner.exe命令 -->
    <property name="jarsigner" location="${evn.JAVA_HOME}/bin/jarsigner.exe"/>

    <!-- 任务:生成签名apk -->
    <target name="signedApk" depends="unsignedApk">
        <exec executable="${jarsigner}">
            <arg value="-keystore"/>
            <arg value="${basedir}/mykeystore.keystore"/>
            <arg value="-storepass"/>
            <arg value="123456"/>
            <arg value="-keypass"/>
            <arg value="123456"/>
            <arg value="-signedjar"/>
            <arg value="${signedApkDir}"/>
            <arg value="${unsignedApkDir}"/>
            <arg value="mykeystore"/>
        </exec>
    </target>

</project>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值