前言
本文将介绍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
的大致流程,作以记录,后续有时间再研究每个环节。