Compile Process of Android Application

编译–>DEX–>打包–>签名和对齐

Package Process

上面这张图对上面的步骤以及每步用到的工具进行了细分,概括如下:

Java编译器对工程本身的java代码进行编译,这些java代码有三个来源:app的源代码,由资源文件生成的R文件(aapt工具),以及有aidl文件生成的java接口文件(aidl工具)。产出为.class文件。

.class文件和依赖的三方库文件通过dex工具生成Delvik虚拟机可执行的.dex文件,可能有一个或多个,包含了所有的class信息,包括项目自身的class和依赖的class。产出为.dex文件。

apkbuilder工具将.dex文件和编译后的资源文件生成未经签名对齐的apk文件。这里编译后的资源文件包括两部分,一是由aapt编译产生的编译后的资源文件,二是依赖的三方库里的资源文件。产出为未经签名的.apk文件。

分别由Jarsigner和zipalign对apk文件进行签名和对齐,生成最终的apk文件。

可以将整个打包过程概括为以下几步:

  1. 通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
  2. 处理.aidl文件,生成对应的Java接口文件
  3. 通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件
  4. 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex
  5. 通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
  6. 通过Jarsigner工具,对上面的apk进行debug或release签名
    通过zipalign工具,将签名后的apk进行对齐处理。

关于zipalign工具,根据名字就知道是个zip文件对齐的工具。使得apk中的资源文件偏离文件起始位置4个字节,从而可以通过mmap()直接访问,从而减少RAM占用。

下图是谷歌官网给出的一个典型的apk构建的过程,比较概括。主要包括两个过程,首先是编译过程,编译的内容包括本工程的文件以及依赖的各种库文件,编译的输出包括dex文件和编译后的资源文件。然后是打包过程。配合Keystore对第一步的输出进行签名对齐,生成最终的apk文件。

APK Content

apk包内容包括:

  1. classes.dex…
  2. resources.arsc
  3. assets
  4. res
  5. AndroidManifest.xml
  6. META-INF
    7.
    其中:
    res中图片和raw文件下内容保持原样,res中其他xml文件内容均转化为二进制形式;assets文件内容保持原样
    res中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager

Gradle Process

Android工程通过gradle文件管理各项配置,gradle文件利用DSL(Domain Specific Language)语言描述配置,并使用Groovy语言处理编译逻辑。一个典型的Android工程结构如下:

在这里gradle文件分布在几个不同的层级,Project层级以及Module层级。

  1. Project层级的settings.gradle描述的是该Project包含哪些Module
    1
    include ':presentation', ':qamodel', ':chatcommonmodule', ':qa', ':unlimit'

Project层级的build.gradle描述的是作用于所有Module的配置,包括gradle版本等。

  1. Module层级的build.gradle。每个Module下都有一个作用于该Module的build.gradle文件,描述了该Module相关的配置。这些配置主要包括:BuildTypes,ProductFlavors,Dependency,SigningSettings等。

Reference


[1]Android应用开发编译框架流程与IDE及Gradle概要
[2]Android Gradle权威指南
[3]Gradle 完整指南(Android)