一、 APK 组成解析
在开始解析 Android 构建流程之前,咱们先来看下构建的终究产品 APK 的整体组成
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 进行并排比较
② ClassyShark
ClassyShark 能够作为 AS 自带 APK 剖析器的补充,帮咱们剖析 dex 中的详细数据,以及检查 APK 中的总办法数以及各个模块的办法数散布。
1.2 Dex 知识点拓宽
当咱们在 Android 检查一个 APK 的时分,能够看到右上角有 Defined Methods 和 Referenced Methods,但大多数人或许不知道这两者的差异,这儿简略阐明下:
Defined Methods:在这个 Dex 中定义的办法 Referenced Methods:Defined Methods 以及 Defined Methods 引证到的办法
Android 有 64K 引证限制,当 type_ids、method_ids 或者 field_ids 超越 65536(64 * 1024)的时分,需要进行 dex 分包,为了 Dex 的数量尽或许少,咱们需要尽量完结「Dex 信息有效率」的提升
Dex 信息有效率 = Defined Methods 数量 / Referenced Methods 数量
二、 构建源码导读
当咱们用 Android Studio 进行安装包构建的时分,会发现其实是运转了一连串的 Task,也便是说其实是这些 task 的合作,终究构建出咱们的 APK 的。
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 的代码逻辑。
生成 BuildConfig 文件,是经过 ApplicationTaskManager 中经过 createBuildConfigTask 来创建对应的 task。
顺着代码逻辑,咱们找到终究真实完结这个逻辑的是:GenerateBuildConfig 这个 task,GenerateBuildConfig 是继承自 BaseTask,这儿有个小技巧是,Task 中真实的履行逻辑都是在带着 @TaskAction 注解的办法上的,所以咱们能很快找到对应的 generate() 办法。能够看到生成 BuildConfig 整体的逻辑仍是比较简略的,其实便是将 build.gradle 中自带的属性以及咱们自定义的属性进行读取,然后经过 JavaWriter 生成对应的 BuildConfig 文件。
2.3 获取所有 task 对应的类名
看到上面的例子,或许有些人会抛出一个疑问便是那咱们怎样确认构建中履行的 task 具体对应哪个类呢,这儿供给一个小技巧,其实咱们能够在 taskGraph 构建完结之后,将所有 task name 以及对应的 class 进行打印。例如在 build.gradle 中加入这个代码之后,咱们在运转的时分,就会把 task 所对应的类名也都一起打印出来。
三、构建流程整理
能够看到 Android 构建中会涉及到多个东西,咱们能够经过 open $ANDROID_HOME/build-tools 来检查相关的构建东西
四、手动构建 APK
最终咱们经过命令行来手动打包一个可履行的 APK,能让咱们对 APK 构建的了解更加深入。首先需要准备下 代码、资源文件、AndroidManifest 这些构建 APK 的必要文件
① 经过 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