一、 APK 组成解析


在开始解析 Android 构建流程之前,咱们先来看下构建的终究产品 APK 的整体组成

APK 是怎么来的?- Android 构建流程解析

APK 主要由五个部分组成,分别是: Dex:.class 文件处理后的产品,Android体系的可履行文件 Resource:资源文件,主要包括 layout、drawable、animator,经过 R.XXX.id 引证 Assets:资源文件,经过 AssetManager 进行加载 Library:so 库存放目录 META-INF:APK 签名有关的信息

1.1 Apk 剖析东西

工欲善其事,必先利其器,既然想剖析 APK 必定少不了好用的东西

① Android Studio 自带的 APK 剖析器

经过 APK 剖析器,咱们能够完结这些操作 1、检查 APK 中文件(如 DEX 和 Android 资源文件)的肯定巨细和相对巨细 2、了解 DEX 文件的组成 3、快速检查 APK 中文件(如 AndroidManifest.xml)的终究版别 4、对两个 APK 进行并排比较

APK 是怎么来的?- Android 构建流程解析
APK 是怎么来的?- Android 构建流程解析

② ClassyShark

ClassyShark 能够作为 AS 自带 APK 剖析器的补充,帮咱们剖析 dex 中的详细数据,以及检查 APK 中的总办法数以及各个模块的办法数散布。

APK 是怎么来的?- Android 构建流程解析
APK 是怎么来的?- Android 构建流程解析

1.2 Dex 知识点拓宽

当咱们在 Android 检查一个 APK 的时分,能够看到右上角有 Defined Methods 和 Referenced Methods,但大多数人或许不知道这两者的差异,这儿简略阐明下:

Defined Methods:在这个 Dex 中定义的办法 Referenced Methods:Defined Methods 以及 Defined Methods 引证到的办法

APK 是怎么来的?- Android 构建流程解析

Android 有 64K 引证限制,当 type_ids、method_ids 或者 field_ids 超越 65536(64 * 1024)的时分,需要进行 dex 分包,为了 Dex 的数量尽或许少,咱们需要尽量完结「Dex 信息有效率」的提升

Dex 信息有效率 = Defined Methods 数量 / Referenced Methods 数量
APK 是怎么来的?- Android 构建流程解析

二、 构建源码导读


当咱们用 Android Studio 进行安装包构建的时分,会发现其实是运转了一连串的 Task,也便是说其实是这些 task 的合作,终究构建出咱们的 APK 的。

APK 是怎么来的?- Android 构建流程解析

2.1 源码引进

假如咱们想更了解 Android 的构建流程,对于相关的源码肯定是要有所了解的。那咱们怎样看到这些 Task 相关的源码呢,咱们知道 Android 是用 Gradle 进行构建的,也就意味着这些 task 其实都是放在 Gradle 中,咱们想看 Gradle 中源码的话,能够在 build.gradle 将 Gradle 进行编译。

compileOnly "com.android.tools.build:gradle:3.0.1"

编译完之后,能够在 ApplicationTaskManager#createTasksForVariantScope 中找到创建这些 Task 相关的代码,也就意味着顺藤摸瓜找到这些 Task 的真实完结逻辑。

2.2 BuildConfig Task 详解

这儿以 BuildConfig 文件的生成为例,来整理下怎样检查某个 task 的代码逻辑。

APK 是怎么来的?- Android 构建流程解析

生成 BuildConfig 文件,是经过 ApplicationTaskManager 中经过 createBuildConfigTask 来创建对应的 task。

APK 是怎么来的?- Android 构建流程解析
APK 是怎么来的?- Android 构建流程解析

顺着代码逻辑,咱们找到终究真实完结这个逻辑的是:GenerateBuildConfig 这个 task,GenerateBuildConfig 是继承自 BaseTask,这儿有个小技巧是,Task 中真实的履行逻辑都是在带着 @TaskAction 注解的办法上的,所以咱们能很快找到对应的 generate() 办法。能够看到生成 BuildConfig 整体的逻辑仍是比较简略的,其实便是将 build.gradle 中自带的属性以及咱们自定义的属性进行读取,然后经过 JavaWriter 生成对应的 BuildConfig 文件。

APK 是怎么来的?- Android 构建流程解析
APK 是怎么来的?- Android 构建流程解析

2.3 获取所有 task 对应的类名

看到上面的例子,或许有些人会抛出一个疑问便是那咱们怎样确认构建中履行的 task 具体对应哪个类呢,这儿供给一个小技巧,其实咱们能够在 taskGraph 构建完结之后,将所有 task name 以及对应的 class 进行打印。例如在 build.gradle 中加入这个代码之后,咱们在运转的时分,就会把 task 所对应的类名也都一起打印出来。

APK 是怎么来的?- Android 构建流程解析
APK 是怎么来的?- Android 构建流程解析

三、构建流程整理


APK 是怎么来的?- Android 构建流程解析

能够看到 Android 构建中会涉及到多个东西,咱们能够经过 open $ANDROID_HOME/build-tools 来检查相关的构建东西

APK 是怎么来的?- Android 构建流程解析

四、手动构建 APK


最终咱们经过命令行来手动打包一个可履行的 APK,能让咱们对 APK 构建的了解更加深入。首先需要准备下 代码、资源文件、AndroidManifest 这些构建 APK 的必要文件

APK 是怎么来的?- Android 构建流程解析

① 经过 aapt2 compile 将 res 资源编译成 .flat 的二进制文件

aapt2 compile -o build/res.zip --dir res

② 经过 aapt2 link 将 .flat 和 AndroidManifest 进行连接,转化成不包含 dex 的 apk 和 R.java

aapt2 link build/res.zip -I $ANDROID_HOME/platforms/android-30/android.jar --java build --manifest AndroidManifest.xml -o build/app-debug.apk

③ 经过 javac 将 Java 文件编译成 .class 文件

javac -d build -cp $ANDROID_HOME/platforms/android-30/android.jar com/**/**/**/*.java

④ 经过 d8 将 .class 文件转化成 dex 文件

d8 --output build/ --lib $ANDROID_HOME/platforms/android-30/android.jar build/com/tencent/hockeyli/androidbuild/*.class

⑤ 兼并 dex ⽂件和资源⽂件

zip -j build/app-debug.apk build/classes.dex

⑥ 对 apk 经过 apksigner 进行签名

apksigner sign -ks ~/.android/debug.keystore build/appdebug.apk