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

Posted TonyW92

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何手动完成一次APK打包?----APK编译全过程相关的知识,希望对你有一定的参考价值。


身为一个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:

function findjava ()
    //友情提示,这里不是单引号,是反引号。Esc键下面那个按键
    //表示shell执行命令
    for file int `ls $1`
    do
        if[ -d $1"/"$file ]; then
            findjava $1"/"$file
        else
            echo $1"/"$file >> /home/tonywang/javafile.txt
        fi
    done


dir='/home/tonywang/javaDemo/src'
findjava $dir

以上是关于如何手动完成一次APK打包?----APK编译全过程的主要内容,如果未能解决你的问题,请参考以下文章

在docker搭建android编译打包环境实践

如何把ndk编译出来的可执行文件伪装成so打包到apk中

APK反编译得工具总结(转载)

如何反编译android应用并重新打包

APK反编译

Android对apk源代码的改动--反编译+源代码改动+又一次打包+签名附HelloWorld的改动实例