android开发

App 的编译和打包流程

2020-10-28  本文已影响0人  凯玲之恋

1、APK 的组成

我们都知道,APK 其实是一个 zip 类型的压缩包,而一个典型的 APK 通常都会包含了以下七部分的内容:
我们都知道,APK 其实是一个 zip 类型的压缩包,而一个典型的 APK 通常都会包含了以下七部分的内容:

2、APK 的编译打包流程

APK 打包流程图
打包流程可简述为如下 八个步骤:
处理.aidl file
1、首先,.aidl(Android Interface Description Language)文件需要通过 aidl 工具转换成编译器能够处理的 Java 接口文件。
打包资源文件AAPT
2、同时,资源文件(包括 AndroidManifest.xml、布局文件、各种 xml 资源等等)将被 AAPT(Asset Packaging Tool)(Android Gradle Plugin 3.0.0 及之后使用 AAPT2 替代了 AAPT)处理为最终的 resources.arsc,并生成 R.java 文件以保证源码编写时可以方便地访问到这些资源。
编译Compiler
3、然后,通过 Java Compiler 编译 R.java、Java 接口文件、Java 源文件,最终它们会统一被编译成 .class 文件。

生成dex文件
4、因为 .class 并不是 Android 系统所能识别的格式,所以还需要通过 dex 工具将它们转化为相应的 Dalvik 字节码(包含压缩常量池以及清除冗余信息等工作)。这个过程中还会加入应用所依赖的所有 “第三方库”
ApkBuilder 生成未签名apk
5、下一步,通过 ApkBuilder 工具将资源文件、DEX 文件打包生成 APK 文件。
Jarsigner签名
7、然后,通过签名工具 Jarsigner 或者其它签名工具对 APK 进行签名得到签名后的 APK。如果是在 Debug 模式下,签名所用的 keystore 是系统自带的默认值,否则我们需要提供自己的私钥以完成签名过程。
ZipAlign对齐
8、最后,如果是正式版的 APK,还会利用 ZipAlign 工具进行对齐处理,以提高程序的加载和运行速度。而对齐的过程就是将 APK 文件中所有的资源文件距离文件的起始位置都偏移4字节的整数倍,这样通过 mmap 访问 APK 文件的速度会更快,并且会减少其在设备上运行时的内存占用。

为什么 XML 资源文件要从文本格式编译成二进制格式?

主要基于以下 两点原因:

Android 资源管理框架又是如何快速定位到最匹配资源的?

主要基于两个文件,如下所示:

3、签名算法的原理

什么是签名?

在 Apk 中写入一个 “指纹”。指纹写入以后,Apk 中有任何修改,都会导致这个指纹无效,Android 系统在安装 Apk 进行签名校验时就会不通过,从而保证了安全性。

那么,为什么要签名?
主要有 两点原因,如下所示:

数字摘要

对一个任意长度的数据,通过一个 Hash 算法计算后,都可以得到一个固定长度的二进制数据,这个数据就称为 “摘要”。

在签名和校验的流程之中,应用了许多密码学的知识,这里我们需要先大致了解一下。

Hash(散列算法)的基础原理

Hash 算法就是 将数据(如一段文字)运算变为另一固定长度值。它的特点主要有如下 三点:

签名和校验的主要过程

签名就是 在摘要的基础上再进行一次加密,对摘要加密后的数据就可以当作数字签名。
签名过程:
签名过程可以细分为 三步,如下所示:

数字证书

数字证书是 身份认证机构(Certificate Authority)颁发的,主要包含了以下 六类信息:

接收方收到消息后,需要先向 CA 验证证书的合法性,再进行签名校验。

需要注意的是,Apk 的证书通常是自签名的,也就是由开发者自己制作,没有向 CA 机构申请。Android 在安装 Apk 时并没有校验证书本身的合法性,只是从证书中提取公钥和加密算法,这也正是对第三方 Apk 重新签名后,还能够继续在没有安装这个 Apk 的系统中继续安装的原因

keystore 和证书格式

keystore 文件中包含了 私钥、公钥和数字证书。根据编码不同,keystore 文件分为很多种,Android 使用的是 Java 标准 keystore 格式 JKS(Java Key Storage),所以通过 Android Studio 导出的 keystore 文件是以 .jks 结尾的。

keystore 使用的 证书标准是 X.509,X.509 标准也有多种 编码格式,常用的有两种:pem(Privacy Enhanced Mail)和 der(Distinguished Encoding Rules)。jks 使用的是 der 格式,但是,Android 也支持直接使用 pem 格式的证书进行签名。

下面,我们了解下两种证书编码格式的区别,如下所示:

jarsigner 和 apksigner 的区别

Android 提供了 两种对 Apk 的签名方式,一种是基于 JAR 的签名方式,另一种是基于 Apk 的签名方式,它们的 主要区别在于使用的签名文件不一样:jarsigner 使用 keystore 文件进行签名;而 apksigner 除了支持使用 keystore 文件进行签名外,还支持直接指定 pem 证书文件和私钥进行签名。

在我们签名时,除了要指定 keystore 文件和密码外,也要指定 alias 和 key 的密码,这是为什么呢?

keystore 是一个密钥库,也就是说它可以存储多对密钥和证书,keystore 的密码是用于保护 keystore 本身的,每一对密钥和证书是通过 alias 来区分的。所以 jarsigner 是支持使用多个证书对 Apk 进行签名的,apksigner 也同样支持。

Android Apk V1 验证签名的原理

Android Apk V1 验证签名的过程主要可以分为如下 四步:

参考

深入探索编译插桩技术(一、编译基础)

上一篇下一篇

猜你喜欢

热点阅读