ZipAlign
zipalign是一个存档对齐工具,可为Android应用程序(APK)文件提供重要的优化。目的是确保所有未压缩数据以相对于文件开头的特定对齐开始。具体来说,它会导致APK中的所有未压缩数据(如图像或原始文件)在4字节边界上对齐。对齐以后,系统就能更加快速的调用APP内的资源
配置
只需要在项目中gradle中配置zipAlignEnabled, 在构建的时候就会自动帮我们执行
buildTypes {
release {
//Zipalign优化
zipAlignEnabled true
}
debug {
//Zipalign优化
zipAlignEnabled false
}
}
- 当然也可以手动对齐
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
-f :覆盖现有的outfile.zip
-v :详细输出
-p :outfile.zip应该对infile.zip中的所有共享对象文件使用相同的页面对齐方式
-c :确认给定文件的对齐方式
- 确认是否对齐
zipalign -c -v <alignment> existing.apk
ZipAlign on V1 & V2
- 如果您使用apksigner,则只能在APK文件签名之前执行zipalign 。如果您使用apksigner对APK进行签名并对APK进行进一步更改,则其签名将失效。
- 如果您使用jarsigner,则只能在APK文件签名后执行zipalign 。
Q: V2 signer为什么不能在签名后使用zipAlign呢?
A: 这是因为在V1签名中信息摘要是按照文件的颗粒度来执行的, 而V2签名中则是将apk中所有数据的字节划分为1M大小的bucket再进行摘要.
在 v1 仅针对单个 ZIP 条目进行验证,因此,在 APK 签署后可进行许多修改 — 可以移动甚至重新压缩文件。事实上,编译过程中要用到的 ZIPalign 工具就是这么做的,它用于根据正确的字节限制调整 ZIP 条目,以改进运行时性能。
而 v2 签名将验证归档中的所有字节,而不是单个 ZIP 条目,因此,在签署后无法再运行 ZIPalign(必须在签名之前执行)
引用一张构建时 V1 和 V2的图

为什么要对齐
在文件对齐后, 就可以使用mmap来直接读写apk文件.
正常的IO读写需要借助内核态的页缓存, 也就是 磁盘 ->内核页缓存 ->用户主存
mmap借助映射可以跳过内核页缓存, 只需要磁盘 ->用户主存
Linux是以page为单位管理内存的,mmap也是以page为单位建立映射的,因此offset必须是按page size对齐的(不对齐的话就会映射失败)。文件是有长度的,offset和offset+length的值都应该小于被映射文件的长度。
具体可以参考 https://zhuanlan.zhihu.com/p/71517406
