1、概述
AAPT即Android Asset Packaging Tool,在SDK的build-tools目录下。该工具可以查看、创建、更新ZIP格式的文档附件(zip、jar、apk)。也可将资源文件编译成二进制文件,尽管你可能没有直接使用过aapt工具,但是build scripts和IDE插件会使用这个工具打包apk文件构成一个Android应用程序。在使用aapt之前需要在环境变量里面配置SDK-tools路径,或者是路径+aapt的方式进入aapt。
2、Android构建APK流程
上图是Google官方发布的一张非常经典的Apk打包流程图。
流程概述:
- 工程的资源文件(res文件夹下的文件),通过AAPT打包成R.java类(资源索引表),以及.arsc资源文件。
- 如果有aidl,通过aidl工具,打包成java接口类
- R.java和aidl.java通过java编译 成想要的.class文件
- 源码class文件和第三方jar或者library通过dx工具打包成dex文件、dx工具的主要作用是将java字节码转换成Dalvik字节码,在此过程中会压缩常量池,消除一些冗余信息等。
- Apkbuilder工具会将所有没有编译的资源、.arsc资源、.dex文件打包到一个完成apk文件中。
- 签名,5中完成apk通过配置的签名文件,jarsigner工具会对齐签名。得到一个签名后的apk
- ZipAlign工具对6中的signed.apk进行对齐处理,所谓对齐,主要过程是将apk包中所有的资源文件距离文件其实偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用主要是为了减少运行时内存的使用。
总结:
结合实际主题资源包打包需求,我们只分析AAPT打包命令说明、签名工具的使用(window环境和linux环境)、ZipAlign对齐工具的使用。
3、AAPT打包命令说明
android 编译资源打包资源文件的命令。
- -d:包括一个或多个设备资源,由逗号分隔;
- -f:覆盖现有的文件命令,加上后编译生成直接覆盖目前已经存在的R.java;
- -m:使生成的包的目录放在-J参数指定的目录;
- -u:更新现有的包 u = update;
- -v:详细输出,加上此命令会在控制台输出每一个资源文件信息,R.java生成后还有注释。
- -x:创建扩展资源ID;
- -z:需要本地化的资源属性标记定位。
- -M:AndroidManifest.xml的路径
- -0:指定一个额外的扩展. apk文件将不会存储压缩
- -g:制定像素迫使图形的灰度
- -j:指定包含一个jar或zip文件包,这个命令很特别
- –debug-mode:指定的是调试模式下的编译资源;
- –min-sdk-versopm VAL:最小SDK版本 如是7以上 则默认编译资源的格式是 utf-8
- –target-sdk-version VAL:在androidMainfest中的目标编译SDK版本
- –app-version VAL:应用程序版本号
- –app-version-name TEXT:应该程序版本名字;
- –custom-package VAL:生成R.java到一个不同的包
- –rename-mainifest-package PACKAGE:修改APK包名的选项;
- –rename-instrumentation-target-package PACKAGE:重写指定包名的选项;
- –utf16:资源编码修改为更改默认utf – 16编码;
- –auto-add-overlay:自动添加资源覆盖
- –max-res-version:最大资源版本
- -I:指定的SDK版本中android.jar的路径
- -A:assert文件夹的路径
- -G:一个文件输出混淆器选项,后面加文件逗号隔开.
- -P:指定的输出公共资源,可以指定一个文件 让资源ID输出到那上面;
- -S:指定资源目录 一般是 res
- -F:指定把资源输出到 apk文件中
- -J:指定R.java输出的路径
- raw-file-dir:附加打包进APK的文件
该命令也是aapt最核心、最复杂的命令。这边我只尝试了一下简单的实践,讲工程的资源编译到一个包里。下面是命令
aapt package -f -S ..\SkinChangeOverlay\SkinChangeOverlay\res -M ..\SkinChangeOverlay\SkinChangeOverlay\AndroidManifest.xml -I ..\android.jar -F ..\SkinChangeOverlay\output_unsign.apk
4、对齐处理(zipalign)
zipalign 是一种归档对齐工具,可对 Android 应用 (APK) 文件提供重要的优化。其目的是要确保所有未压缩数据的开头均相对于文件开头部分执行特定的对齐。具体来说,它会使 APK 中的所有未压缩数据(例如图片或原始文件)在 4 字节边界上对齐。这样一来,即可使用 mmap()
直接访问所有部分,即使其中包含具有对齐限制的二进制数据也没关系。这样做的好处是可以减少运行应用时消耗的 RAM 容量。
在将 APK 文件分发给最终用户之前,必须先使用此工具对齐文件。您可以使用 Android 编译工具来完成此操作。Android Studio 会自动对齐您的 APK。
命令用法:
要对齐 infile.apk 并将其保存为 outfile.apk,请运行以下命令:
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
实际用例:
zipalign -v -p 4 ..\SkinChangeOverlay\output_unsign.apk ..\SkinChangeOverlay\output.apk
5、系统签名
5.1、windows环境
- 获取apksigner.jar
把android源码目录/prebuilts/sdk/tools/windows/lib下的apksigner.jar拷贝到指定目录。
- 平台证书文件(platform.pk8、platform.x509.pem)获取
文件在android源码目录/device/fsl/common/security里
- 系统jks证书生成(只能在linux环境下生成jks证书)
- keytool-importkeypair工具的下载
- 把平台证书文件(platform.pk8、platform.x509.pem)拷贝到与keytool-importkeypair同一个文件夹下。
- keytool-importkeypair命令说明
./keytool-importkeypair -k ./platform.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform
-k 表示要生成的 keystore 文件的名字,这里命名为 platform.keystore
-p 表示要生成的 keystore 的密码,这里是 android
-pk8 表示要导入的 platform.pk8 文件
-cert 表示要导入的platform.x509.pem
-alias 表示给生成的 platform.keystore 取一个别名,这是命名为 platform
实际用例
./keytool-importkeypair -k ccs2/systemsignccs2.jks -p hsae2020 -pk8 ccs2/platform.pk8 -cert ccs2/platform.x509.pem -alias hsaeccs2
然后把生成的jks证书文件拷贝到与apksigner.jar同一目录中。
- apksigner.jar签名工具命令说明
实际用例:
java -jar ..\singer\ccs2\apksigner.jar sign --ks ..\singer\ccs2\systemsignccs2.jks --ks-key-alias hsaeccs2 --ks-pass pass:hsae2020 --out ..\SkinChangeOverlay\output.apk ..\SkinChangeOverlay\output.apk
5.2、linux环境
- 获取signapk.jar
把android源码目录/out/soong/host/linux-x86/framework下的signapk.jar拷贝到指定目录。
- 平台证书文件(platform.pk8、platform.x509.pem)拷贝到与signapk.jar同一目录中。
- 签名命令
java -Djava.library.path=../AndroidP/out/host/linux-x86/lib64 -jar signapk.jar platform.x509.pem platform.pk8 output_unsign.apk output.apk
6、参考资料
https://www.jianshu.com/p/8d691b6bf8b4
https://developer.android.google.cn/studio/command-line/zipalign.html
https://www.jianshu.com/p/e1e2fd05bb62