如何手动完成一次APK打包?----APK编译全过程

来源:互联网 发布:查看oracle端口 编辑:程序博客网 时间:2024/05/21 17:01

身为一个Android工程师,你是否有考虑过一个Android项目工程如何经过编译压缩变成一个APK的呢? 
你又是否编写过打包工具完成多渠道打包呢?

下面我们来解密如何完成一个APK的打包。


这里写图片描述


1、使用Android SDK提供的aapt.exe生成R.Java类文件 
2、使用Android SDK提供的aidl.exe把.aidl转成.java文件(如果没有aidl,则跳过这一步)
3、使用JDK提供的javac.exe编译.java类文件生成class文件
4、使用Android SDK提供的dx.bat命令行脚本生成classes.dex文件
5、使用Android SDK提供的aapt.exe生成资源包文件(包括res、assets、androidmanifest.xml等)
6、使用Android SDK提供的apkbuilder.bat生成未签名的apk安装文件
7、使用jdk的jarsigner.exe对未签名的包进行apk签名


完成一次APK打包一共有7步。从功能上来分,可以分成四步。

  1. 对R文件和Manifest进行编译,相当于产生一个目录,用于查阅代码和资源的位置。
  2. 对java代码的变成产生class文件然后压缩成dex文件,中间可能还有混淆的过程。
  3. 对资源文件的压缩。
  4. 最后签名。

然后我们再来看下分别对应的命令行

  1. 使用aapt命令编译资源文件 aapt package -f -m -J /home/tonywang/javaDemo/gen -S res -I /home/tonywang/sdk/platforms/android-23/android.jar -M AndroidManifest.xml

    其中 -f -m -J /home/tonywang/javaDemo/gen 
    代表按覆盖的形式在gen目录下生成带包路径的R.java,-S res指定资源文件 ,-I 
    /home/tonywang/sdk/platforms/android-23/android.jar 指定使用的android类,-M AndroidManifest.xml指定程序的配置文件

  2. 使用javac命令编译源文件 javac -target 1.7 -bootclasspath 
    /home/tonywang/sdk/platforms/android-23/android.jar -d bin 
    /home/tonywang/javaDemo/gen/com/tony/demo/*.java 
    /home/tonywang/javaDemo/src/com/tony/demo/*.java

    -target:表示编译之后的class文件运行的环境版本 
    -bootclasspath:表示编译需要用到的系统库 
    -d:表示编译之后的class文件存放的目录 这里需要把gen下和src下面的java都编译了。 
    然后还有一个问题就是如果java文件存在多个包名下,就需要一个个列出来,很是麻烦。这里我写了个shell脚本,把所有java名字都存在一个文本里,然后编译对应的文件名列表就好了。脚本贴在下面 
    然后使用这条命令 
    javac -target 1.7 -bootclasspath /home/tonywang/sdk/platforms/android-23/android.jar -d bin @names.txt

  3. 使用dx命令,将class文件转化成dex 
    dx –dex –output=/home/tonywang/javaDemo/bin/classes.dex /home/tonywang/javaDemo/bin/

  4. 使用aapt命令生成资源包文件(编码AndroidManifest.xml,resource.arsc等) 
    aapt package -f -A assets -S res -I /home/tonywang/sdk/platforms/android-23/android.jar -M AndroidManifest.xml -F /home/tonywang/javaDemo/bin/javaDemo

  5. 使用apkbuilder命令来编译 
    apk apkbuilder /home/tonywang/javaDemo/bin/javaDemo_unsigned.apk -v -u -z 
    /home/tonywang/javaDemo/bin/javaDemo -f 
    /home/tonywang/javaDemo/bin/javaDemo/classes.dex -rf 
    /home/tonywang/javaDemo/src

  6. 使用keytool来产生一个keystore文件 
    keytool -genkey -alias demo_test -keyalg RSA -validity 20000 -keystore demo.keystore

  7. 使用jarsigner签名apk文件 
    jarsigner -keystore /home/tonywang/javaDemo/demo.keystore -storepass 123456 -keypass 
    123456 -signedjar /home/tonywang/javaDemo/bin/javaDemo_signed.apk 
    /home/tonywang/javaDemo/bin/javaDemo_unsigned.apk

至此,我们就完成了一次APK的编译。 
如果你需要多个渠道打包,可以编写一个Ant脚本,或者gradle脚本。 
PS.以上所有命令都基于Linux系统


附上查找所有java文件的脚本 
findJava.sh:

<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">function <span class="hljs-function" style="box-sizing: border-box;">findjava</span> (){    //友情提示,这里不是单引号,是反引号。Esc键下面那个按键    //表示shell执行命令    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> file int `ls <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$1</span>`    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">do</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>[ <span class="hljs-operator" style="box-sizing: border-box;">-d</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$1</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/"</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$file</span> ]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">then</span>            findjava <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$1</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/"</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$file</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">echo</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$1</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/"</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$file</span> >> /home/tonywang/javafile.txt        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">fi</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">done</span>}dir=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'/home/tonywang/javaDemo/src'</span>findjava <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$dir</span></code>
0 0
原创粉丝点击