前言
本文将介绍Android从一个项目打包成APK的过程,其中涉及Android Java和Kotlin文件、资源文件、清单文件、依赖jar包和so库等在打包过程中处理。
步骤
总体的打包流程如下图,下面就介绍下详细的打包步骤。
1、将aidl文件编译成java文件
在构建过程中,Gradle会调用AIDL编译器将.aidl文件转化为.java文件。
2、aapt2处理resource文件
使用AAPT编译res目录下资源文件,把部分xml文件编译成二进制文件,同时生成R.java和resource.arsc文件。
R.java: 我们开发中就能接触到,为资源分类,R.layout 、R.drawable、R.string为项目中的资源文件提供了一个索引,包含布局、颜色、尺寸、字符串等
resource.arsc : 保存了应用的所有已编译资源的二进制数据。
①、包含应用中所有资源项的值,如字符串、颜色、尺寸、样式等。每个资源项都与一个资源 ID 相关联,这些 ID 是由 R.java 文件生成的常量。
②、包含了每种资源类型的描述信息,比如 layout、string、color 、drawable等。每种类型都包含多个资源项。
③、文件包含与不同设备配置相关的资源信息,如针对不同语言、屏幕密度、屏幕大小、方向等配置的资源。
将aidl生成的xxx.java文件和aapt编译资源文件生成的R.java进行合并。
3、JavaC编译生成.javac文件
此步骤是项目中所有的java代码、aidl生成的xxx.java文件还有R.java文件通过JavaCompiler编译器编译生成.class文件。
4、dx工具生成classes.dex
将步骤3中生成的.classes文件和三方库中编译生成的.classes文件通过dx工具,生成classes.dex,这就是Dalvik虚拟机所能识别和执行的文件类型。
5、APKBuilder工具生成apk
将步骤4中生成的classes.dex,项目中非Java文件(如清单文件、so库)、assets目录下文件,三方非Java资源通过工具apkbuilder生成未签名的apk包。
6、Zipalign优化与签名发布
Zipalign(对齐处理) 工具,对APK 中的所有未压缩数据(例如图片)在 4 字节边界上对齐。这使得CPU读写就会更高效,以提高应用在设备上的运行性能。Zipalign 是 Android SDK 提供的一个优化工具,确保 APK 中的数据经过对齐,从而减少应用启动时间和内存占用。
步骤5中生成了未签名的apk文件,开发期间使用 AS提供的默认 debug 密钥自动签名,发布应用时,必须使用密钥库文件(keystore)进行签名。密钥库通常是一个 .jks 文件,包含应用的签名信息。

编译实例

通过Gradle构建工具进行编译打包,控制台中可以看到构建任务执行的过程,可以看到和上述描述的构建打包流程是一致的。
//准备编译release版本
:app:preReleaseBuild
:app:dataBindingMergeDependencyArtifactsRelease
:app:generateReleaseResValues
//aidl编译器转化aidl文件为java文件
:app:compileReleaseAidl
//生成、合并、处理xml文件,如layout.xml、color.xml等
:app:generateReleaseResources
:app:mergeReleaseResources
:app:dataBindingGenBaseClassesRelease
:app:processReleaseResources
//KotlinC 编译kotlin成.class文件
:app:compileReleaseKotlin
:app:javaPreCompileRelease
//JavaC 编译java
:app:compileReleaseJavaWithJavac
.....
//合并Jni目录
:app:mergeReleaseJniLibFolders
:app:mergeReleaseNativeLibs
.....
//解糖化 Release 文件依赖项
:app:desugarReleaseFileDependencies
:app:mergeExtDexRelease
//合并所有Dex文件
:app:mergeDexRelease
.....
//生成、处理、合并Assets、项目资源文件、Java文件
:app:generateReleaseAssets
:app:mergeReleaseAssets
:app:compressReleaseAssets
:app:processReleaseJavaRes
:app:mergeReleaseJavaResource
.....
//打包
:app:packageRelease
编译打包后,对apk文件进行解压,我们可以发现生成了classes.dex、resources.arsc ,AndroidManifest.xml清单文件、kotlin/文件夹 , res/文件夹 , assets和so库会原封不动打到apk对应目录中。

上图中我们还可以发现,除了有classes.dex还有classes2.dex两个.dex文件,这是由于应用的代码量超出了单个 .dex 文件的 64K 方法数限制,这个限制包括应用的所有方法(包括 Android SDK、第三方库和应用自身的代码),导致构建工具自动启用了 MultiDex 机制,将代码分割到多个 .dex 文件中。通过 MultiDex,应用可以突破这个限制,并继续正常运行。
结尾
至此,我们了解了Android项目打包成apk的大致流程,作以记录,后续有时间再研究每个环节。









