Android安装包的后缀都是.apk, apk是Android Package的缩写。 解压apk文件后包含AndroidManifest.xml、assets目录、classes.dex(还可能有 classes2.dex,classes3.dex...classesN.dex)、lib目录、META-INF目录、res目录和resources.arsc。
AndroidManifest.xml对应源代码中的AndroidManifest.xml, 但这里是编译过的,文件内容已经不同了。
assets对应源代码的assets目录, 是直接复制过来的。
classes.dex是包含所有Java文件对应的字节码。
lib目录对应源代码中的libs目录,包含so文件。
META-INF目录包含CERT.RSA、CERT.SF、MANIFEST.MF等, 保存了各个资源文件的SHA1值,用于校验资源文件是否被篡改,从而防止二次打包时资源文件被替换。
res目录对应源码的res目录, 包含各种图片、xml等。
resources.arsc包含了各个资源文件的映射, 可以理解为索引, 通过该文件能找到对应的资源文件信息。
打包过程:
这张图清晰的描述了整个打包过程, 可以跟Android SDK的build-tools目录对应起来。
Android编译打包过程主要分为如下7个步骤:
1. aapt过程
使用文件aapt/aapt2打包res目录资源文件, 生成R.java、resources.arsc和res目录。
R.java保存了所有id的值, 数据类型都是整型。
2、aidl生成Java文件
AIDL是Android Interface Definition Language的简称, 是Android跨进程通讯的一种方式。 检索工程里所有的aidl文件,并转换为对应的Java文件。
3、 Javac编译。
使用JDK里的javac编译R.java、aidl生成的Java文件、Java源文件, 并生成.class文件。
4、 生成dex文件。
通过dx工具将.class文件生成为classes.dex, 目前的gradle multi-dex编译方式会生成classes2.dex ... classesN.dex。
5、 生成apk文件。
使用ApkBuilder将resources.arsc、res目录、AndroidManifest.xml、assets目录、dex文件打包成apk, 具体逻辑是在com.android.sdklib.build.ApkBuilder中实现的。
6、签名apk文件。
使用apksigner为安装包添加签名信息。
7、 zipalign优化签名包。
使用zipalign工具对签名包进行内存对齐操作, 即优化安装包的结构。
综上所述, Android SDK中build-tools目录提供了各种程序, 都是独立可运行的,可以认为Android Studio编译打包过程是对这些工具的封装。
只打包部分代码/资源需要设置gradle sourceSets, 多渠道打包可以参考美团做法或使用mulchannel
参考:
Android gradle SourceSets介绍与使用
Android Studio下项目构建的Gradle配置及打包应用变体
美团Android自动化之旅—生成渠道包
深入理解gradle编译-Android进阶篇