• android APK 文件的生成过程


    步骤:

    1. 用 aapt工具生成R文件
    aapt  package  -m -J  gen目录 -M AndroidManifest.xml  -S res目录  -I 编译版本sdk的android.jar的路径
    如: "sdk安装目录platformsandroid-8android.jar"

    2. 用 aidl.exe 工具将.aidl文件生成对应的java类

    3. 用 javac 编译所有的java文件,生成对应class文件。

    4. 用 jar 命令将上面的class文件生成一个 jar包

    5  用 proguard.jar 将上面的jar包混淆, (混淆应该是对class文件进行的,上面即使打包了可能也要解包,所以第4步可以省)

    6. 用 dx.bat(调用了dx.jar)工具将混淆后的class文件,打包成一个 class.dex 文件

    7. 用 aapt.exe 工具将 资源文件 打包成一个 resources.ap_  文件(好像对整个res目录都压缩了,但是解压apk后图片又是分目录存放的)

    8. 用 apkbuilder.bat(调用了lib目录的sdklib.build.ApkBuilderMain)将 dex文件和打包后的资源文件 生成 apk文件

    9. 用 jarsigner 对apk 进行签名,生成签名后的 apk 文件

    10.用 zipalign.exe 工具对签名后的 apk 进行优化,生成最终的 apk 文件

    下面是对应的ant脚本(去掉了混淆的步骤)。

    build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project name="DailyBuild" default="buildAll" basedir=".">
    
        <!-- 导入可配置文件 -->
        <import file="build_option.xml" />
    
        <!--导入构建过程定义文件 -->
        <import file="build_common.xml" />
    
        <!-- 调用common_build.xml中的target,按顺序组织,执行构建         <antcall target="obfuscate" />-->
        <target name="buildAll">
            <antcall target="init" />
            <antcall target="generate" />
            <antcall target="aidl" />
            <antcall target="compile" />
            <antcall target="package" />
            <antcall target="dex" />
            <antcall target="package_resouces" />
            <antcall target="release" />
            <antcall target="sign" />
            <antcall target="zipalign" />
        </target>
    </project>
    View Code

    build_common.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project name="build_common" default="" basedir=".">
    
        <property name="src" value="src"/>                        <!-- 运行时源代码目录 -->
        <property name="res" value="res"/>                        <!-- 运行时资源目录 -->
        <property name="lib" value="libs"/>                        <!-- 运行时库目录 -->
        <property name="assets" value="assets"/>                <!-- 运行时assets目录 -->
        <property name="bin" value="bin"/>                        <!-- 编译输出结果目录 -->
        <property name="classes" value="classes"/>                <!-- 运行时classes输出目录 -->
        <property name="gen" value="gen" />                        <!-- 运行时gen目录 -->
        <property name="autotest" value="autotest" />            <!-- 自动化测试目录 -->
        <property name="dex" value="classes.dex"/>                <!-- dex路径 -->
        
    
        <property name="android_platform_tools" value="${android_home}/platform-tools"/>
        <property name="android_framework" value="${android_home}/platforms/android-${android_version}/framework.aidl"/>    
        <property name="aapt" value="${android_platform_tools}/aapt"/>
        <property name="aidl" value="${android_platform_tools}/aidl"/>
        <property name="adb" value="${android_platform_tools}/adb"/>
        <property name="dx" value="${android_platform_tools}/dx${bat}"/>
        <property name="apkbuilder" value="${android_home}/tools/apkbuilder${bat}"/>
        <property name="zipalign" value="${android_home}/tools/zipalign"/>
        <property name="androidjar" value="${android_home}/platforms/android-${android_version}/android.jar"/>    
    
        <!-- 执行初始化操作 -->
        <target name="init">
            <echo>start initialize...</echo>
            <delete includeemptydirs="true" failonerror="false">
                <fileset dir="${classes}" defaultexcludes="true"/>
                <fileset dir="${gen}" defaultexcludes="true"/>
                <fileset dir="${bin}" defaultexcludes="true"/>
            </delete>
            
            <mkdir dir="${bin}" />
            <mkdir dir="${classes}" />
            <mkdir dir="${gen}" />
            <mkdir dir="${lib}" />
        </target>
    
        <!-- 生成R.java -->
        <target name="generate">
            <echo>generate R.java ...</echo>
            <exec executable="${aapt}" failonerror="true">
                <arg value="package" />
                <arg value="-m" />
                <arg value="-J" />
                <arg value="${gen}" />
                <arg value="-M" />
                <arg value="AndroidManifest.xml" />
                <arg value="-S" />
                <arg value="${res}" />
                <arg value="-I" />
                <arg value="${androidjar}" />
            </exec>
        </target>
    
        <!-- 将aidl文件转换为java -->
        <target name="aidl">
            <echo>convert .aidl files to java...</echo>
            <apply executable="${aidl}" failonerror="true">
                <arg value="-p${android_framework}" />
                <arg value="-I${src}" />
                <arg value="-o${gen}" />
                <fileset dir="${src}">
                    <include name="**/*.aidl"/>
                </fileset>
            </apply>
        </target>
    
        <!-- 编译项目的.java文件 -->
        <target name="compile">
            <echo>compile source code...</echo>
            <echo>>>>> debug默认打开,异常上报的还原功能依赖于它</echo>
            <javac encoding="${encoding}" 
                debug="true" 
                extdirs="" 
                target="1.5" 
                destdir="${classes}" 
                bootclasspath="${androidjar}">
                <src path="${src}"/>
                <src path="${gen}"/>
                
                <classpath>
                    <fileset dir="${lib}" includes="*.jar"/>
                </classpath>
             </javac>
        </target>
    
        <!-- 将class文件打包为jar -->  
        <target name="package">
            <echo>Packing compile results...</echo>
            <jar basedir="${classes}" destfile="temp.jar"/>
            <echo>Copy jar to test directory...</echo>
            <copy file="temp.jar" todir="${autotest}"/>
        </target>
    
        <!-- 对打包后的结果进行混淆 -->
        <target name="obfuscate" if="${release}">
            <echo>start obfuscate ...</echo>
            <delete includeemptydirs="true">
                <fileset dir="${classes}" defaultexcludes="true"/>
            </delete>
            <java jar="${proguard_home}/lib/proguard.jar" fork="true" failonerror="true">
                <jvmarg value="-Dmaximum.inlined.code.length=32"/>
                <arg value="-injars temp.jar"/>                    <!-- 输入为class目录,而不是jar包,可以提高速度 -->
                <arg value="-outjars ${classes}"/>                <!-- 输出为class目录,而不是jar包,可以提高速度 -->
                <arg value="-libraryjars ${androidjar}"/>            
                <arg value="-libraryjars ${lib}"/>                    <!-- 混淆依赖的库文件,指定目录即可 -->
                <arg value="-printmapping ${bin}/mapping.txt"/>        <!-- 混淆mapping信息 -->    
                <arg value="@proguard.cfg"/>                        <!-- 混淆参数定义 -->
            </java>
        </target>  
        
        <!-- 将未混淆的classes文件打包为dex文件 -->
        <target name="dex">
            <echo>Coverting obfuscated class files to dex file...</echo>
            <apply executable="${dx}" failonerror="true" parallel="true">
                <arg value="-JXms1024m" />
                <arg value="-JXmx1024m" />
                <arg value="-JXss160k" />            
                <arg value="--dex" />
                <arg value="--num-threads=4" />
                <arg value="--output=${dex}" />
                <arg path="${classes}" />
                <fileset dir="${lib}" includes="*.jar"/>
            </apply>
        </target>
        
        <!-- 打包项目的资源文件 -->
        <target name="package_resouces">
            <echo>Package res and assets...</echo>
            <exec executable="${aapt}" failonerror="true">
                <arg value="package" />
                <arg value="-f" />
                <arg value="-M" />
                <arg value="AndroidManifest.xml" />
                <arg value="-S" />
                <arg value="${res}" />
                <arg value="-A" />
                <arg value="${assets}" />
                <arg value="-I" />
                <arg value="${androidjar}" />
                <arg value="-F" />
                <arg value="${file_name}.ap_" />
            </exec>
        </target>
    
        <!-- 将资源文件及dex文件打包到一起 -->
        <target name="release">
            <echo>package dex and resources ...</echo>
            <exec executable="${apkbuilder}" failonerror="true">
                <arg value="${file_name}.apk" />
                <arg value="-u" />
                <arg value="-z" />
                <arg value="${file_name}.ap_" />
                <arg value="-f" />
                <arg value="${dex}" />
                <arg value="-rf" />
                <arg value="${src}" />
                <arg value="-rj" />
                <arg value="${lib}" />
                <arg value="-nf" />
                <arg value="${lib}" />
            </exec>
        </target>
    
        <!-- 对包未混淆的包进行签名 -->
        <target name="sign">
            <echo>Begin sign unobfuscated package...</echo>
            <exec executable="${signer}" failonerror="true">
                <arg value="-verbose"/>
                <arg value="-keystore"/> 
                <arg value="${keystore}"/>
                <arg value="-storepass"/>
                <arg value="${storepass}"/>
                <arg value="-keypass"/>
                <arg value="${keypass}"/>
                <arg value="-signedjar"/>
                <arg value="${file_name}_signed.apk"/>
                <arg value="${file_name}.apk"/>
                <arg value="${keyname}"/>
            </exec>    
        </target>
        
        <!-- 对未混淆签名包做优化 -->
        <target name="zipalign">
            <echo>zipalign signed apk ...</echo>
            <exec executable="${zipalign}" failonerror="true">
                <arg value="-v" />
                <arg value="4" />
                <arg value="${file_name}_signed.apk" />
                <arg value="${bin}/${file_name}_${cur_time}.apk" />
            </exec>
        </target>
    
    </project>
    View Code

    build_option.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project name="option" default="" basedir=".">    
    
        <property environment="env" />                                                <!-- 环境变量 -->
        <property name="ws" value="${env.WORKSPACE}"/>                                <!-- 取服务器Woskspace路径 -->
        <property name="isCI" value="false"/>                                        <!-- true表示服务器环境,false表示本地环境 -->
        <available file="${ws}/build.xml" property="isCI"/>                            <!-- 判断是否是持续集成服务器环境 -->
        <property name="android_sdk_path"  value="${env.ANDROID_SDK_18_2204_16}" />    <!-- 取sdk路径-->
        
        <property name="android_version" value="8"/>    
        <property name="encoding" value="UTF-8"/>        <!-- 文件编码设置 -->    
        <property name="release" value="true"/>            <!-- 默认输出release版本,带混淆 -->
        <condition property="releasetype" value="debug" else="release">
            <not>
                <istrue value="${release}"/>
            </not>
        </condition>
        
        <condition property="bat" value="bat" else="">
            <os family="windows" />
        </condition>
        
        <!-- 判断系统类型 -->
        <condition property="isWindows" value="true" else="false">
            <os family="windows" />
        </condition>
        
        <!-- 根据系统类型,设置服务器Android SDK路径 -->
        <condition property="android_home_accord_ostype" value="${android_sdk_path}" else="D:/android-sdk-windows" >
            <not>
                <istrue value="${isWindows}"/>
            </not>
        </condition>
        
        <!-- 根据系统类型,设置服务器Proguard路径 -->
        <condition property="proguard_path_accord_ostype" value="${env.ANDROID_PROGUARD_4_8}" else="C:/Progra~1/proguard4.4" >
            <not>
                <istrue value="${isWindows}"/>
            </not>
        </condition>
    
        <!-- 安装包名称,如果是本地,设置value的值 -->
        <condition property="file_name" value="RDM" else="${env.BaseLine}">
            <not>
                <istrue value="${isCI}"/>
            </not>
        </condition>
        
        <!-- 本地工作区路径,如:D:/workspace/qqbrowser_android -->
        <condition property="project_path" value="${basedir}" else="${basedir}">
            <not>
                <istrue value="${isCI}"/>
            </not>
        </condition>
        
        <!-- Android SDK路径,如果本地构建,请修改value的值 -->
        <condition property="android_home" value="C:/android-sdk-windows" else="${android_home_accord_ostype}">
            <not>
                <istrue value="${isCI}"/>
            </not>
        </condition>
        
        <!-- Proguard路径,如果本地构建,请修改value的值 -->
        <condition property="proguard_home" value="C:/Progra~1/proguard4.4" else="${proguard_path_accord_ostype}">
            <not>
                <istrue value="${isCI}"/>
            </not>
        </condition>
        
        <!-- 签名使用的jarsigner路径,如果JDK的bin目录路径已加入系统Path,则不用注明具体路径 -->
        <condition property="signer" value="jarsigner" else="jarsigner">
            <not>
                <istrue value="${isCI}"/>
            </not>
        </condition>
        
    
        <property name="config_keystore_name" value="weigou_shop_keystore" />
    
        <!-- 签名文件设置,请将签名文件放到SVN上,并在这里指定签名文件,建议将签名文件放到构建脚本同级目录,${project_path}即为工作目录-->
        <property name="keystore" value="${project_path}/${config_keystore_name}"/>
        
        <!-- 签名的密钥名称设置-->
        <property name="keyname" value="weigou_shop"/>
        <!-- 签名的密码设置-->
        <property name="keypass" value="201310161450"/>
        <!-- 签名的密码设置-->
        <property name="storepass" value="20131016"/>
        
        
        <tstamp>
           <format property="cur_time" pattern="yyyy_MM_dd_hh.mm" locale="zh"/>
        </tstamp>
    
        
    </project>
    View Code


    aidl是 Android Interface definitionlanguage的缩写。
    它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

    aapt即Android Asset Packaging Tool , 在SDK的build-tools目录下:aapt.exe
    该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk). 也可将资源文件编译成二进制文件.

    aapt工具也支持很多子命令。
    aapt l[ist]:列出资源压缩包里的内容。
    aapt d[ump]:查看APK包内指定的内容。
    aapt p[ackage]:打包生成资源压缩包。
    aapt r[emove]:从压缩包中删除指定文件。
    aapt a[dd]:向压缩包中添加指定文件。
    aapt v[ersion]:打印aapt的版本。

  • 相关阅读:
    深入理解JavaScript系列(15):函数(Functions)
    深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP
    深入理解JavaScript系列(2):揭秘命名函数表达式
    深入理解JavaScript系列(3):全面解析Module模式
    深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
    深入理解JavaScript系列(18):面向对象编程之ECMAScript实现(推荐)
    理解Javascript_13_执行模型详解
    深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
    深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP
    深入理解JavaScript系列(11):执行上下文(Execution Contexts)
  • 原文地址:https://www.cnblogs.com/zijianlu/p/3481768.html
Copyright © 2020-2023  润新知