应用的打包流程包括从代码编译到生成可安装的 APK 文件
源代码 (Java/Kotlin) ➔ 编译 ➔ 字节码 (.class 文件) ➔ 转换成 (.dex 文件)
资源文件 ➔ 编译资源 ➔ 生成 R.java ➔ 打包 (AAPT) ➔ APK 文件
APK 文件 ➔ 签名 ➔ zipalign ➔ 发布的 APK
apk是一个压缩包,解压出来得到几类文件和目录
AndroidManifest.xml
:就是 AndroidManifest.xml
classes.dex
和 classes2.dex
,可能还有 classes*.dex
:可以直接在Dalvik虚拟机上加载运行的文件,由java/kotlin文件经过IDE编译生成
resources.arsc
:资源索引表,二进制文件,将使用到类似 @String/name 转换为真正的 ID 引用值
目录 res
:资源目录,包括图片、音频、icon、xml等
目录 META-INF
:签名文件夹
Android 的构建工具放在 ${ANDROID_HOME}/build-tools/<version_code>/
目录下
aapt/aapt2:Android 资源打包工具,新版使用 aapt2
aidl:Android 接口描述语言 *.aidl
转化为 *.java
文件的工具
javac:Java 编译器,编译出 *.class
文件,目录 ${JDK_HOME}/bin/javac
kotlinc:Kotlin 编译器,编译出 *.class
文件,目录 ${IDE}/plugins/Kotlin/kotlinc/bin/kotlinc
dex/d8:转化 *.class
文件为 Davik 虚拟机能识别的 *.dex
文件,新版使用 d8
工具
apkbuilder:生成 apk 包,新版不再提供,替代是 新版使用 ${ANDROID_HOME}/tools/lib/sdklib-<version_code>.jar
里面的类 com.android.sdklib.build.ApkBuilderMain
aapt2
合并
jarsigner: 新版使用 *.jar
文件的签名工具,目录 ${JDK_HOME}/bin/jarsigner
apksigner
在 apk 对齐后进行 apk 的签名
zipalign:apk 字节码对齐工具
1.编译器将源代码转换成 DEX 文件(Dalvik 可执行文件,其中包括在 Android 设备上运行的字节码),并将其他所有内容转换成编译后的资源。
2.打包器将 DEX 文件和编译后的资源组合成 APK 或 AAB。 必须先为 APK 或 AAB 签名,然后才能将应用安装到 Android 设备或分发到 Google Play 等商店。
3.打包器使用调试或发布密钥库为 APK 或 AAB 签名:
如果构建的是 debug 应用(即专门用来测试和分析的应用),则打包器会使用调试密钥库为应用签名。Android Studio 会自动使用调试密钥库配置新项目。
如果构建的是 release 应用,则打包器会使用发布密钥库(需要进行配置)为应用签名。
4.在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,以减少其在设备上运行时所占用的内存。
由图可知包括以下 7 个步骤
aapt过程
aidl生成java文件
javac编译(包含 kotlinc)
生成dex文件
生成apk文件
签名apk文件
zipalign优化签名包
接下来可以愉快地去写打包脚本啦~
最后加上自己总结的流程图 和 工具
graph TB
subgraph apk 打包流程
direction TB
subgraph aapt2 编译
MANIFEST([AndroidManifest.xml])
RES(["res/"])
end
COMPILED_MANIFEST(["AndroidManifest.xml\n(被编译为二进制)"])
ARSC(["resources.arsc\n(资源索引表)"])
COMPILED_RES(["res/\n(xml被编译为二进制,\n图片被压缩,raw原封不动)"])
R([R.java])
MANIFEST --> |aapt2 编译| COMPILED_MANIFEST
RES --> |aapt2 编译| ARSC
RES --> |aapt2 编译| COMPILED_RES
RES --> |aapt2 编译| R
JAVA([.java])
KOTLIN([.kt])
AIDL([.aidl])
AIDL_JAVA([".java\n接口"])
CLASS([.class])
3RD_CLASS([3rd .class])
DEX([.dex])
subgraph 编译成 .class
R --> |javac| CLASS
JAVA --> |javac| CLASS
KOTLIN --> |kotlinc| CLASS
AIDL --> |aidl| AIDL_JAVA --> |javac| CLASS
end
CLASS --> |d8| DEX
3RD_CLASS --> |d8| DEX
ASSETS(["assets/"])
UNSIGNED([app-unsigned.apk])
ALIGIN([app-unsigned-aligin.apk])
SIGNED([app-signed.apk])
subgraph aapt2 合并
COMPILED_MANIFEST --> |aapt2 合并| UNSIGNED
ARSC --> |aapt2 合并| UNSIGNED
COMPILED_RES --> |aapt2 合并| UNSIGNED
DEX --> |aapt2 合并| UNSIGNED
ASSETS --> |aapt2 合并| UNSIGNED
end
UNSIGNED --> |zipaligin 对齐| ALIGIN --> |apk-signer 签名| SIGNED
end
打包流程使用的工具
工具 | 功能 | 工具路径 |
---|---|---|
aapt2 | Android 资源打包 | ${ANDROID_HOME}/build-tools/33.0.2/aapt2 |
aidl | .aidl 编译成 .class | ${ANDROID_HOME}/build-tools/33.0.2/aidl |
javac | .java 编译成 .class | ${JAVA_HOME}/bin/javac |
kotlinc | .kt 编译成 .class | ${IDE}/plugins/Kotlin/kotlinc/bin/kotlinc |
d8 | .class 转化成 .dex | ${ANDROID_HOME}/build-tools/33.0.2/d8 |
zipaligin | apk 字节码对齐 | ${ANDROID_HOME}/build-tools/33.0.2/zipaligin |
apk-signer | apk 签名 | ${ANDROID_HOME}/build-tools/33.0.2/apksigner |