说到安卓应用,
一般的开发者用的比较多的是AndroidStudio
集成开发工具,根据Google
相关的文档说明就可以一步一步做到应用的打包,签名和发布。这更多的是面向单独的应用开发者。
如果接触到安卓源码,我们更想弄清楚当我们编译源码过程中APK
应用是如何默默的打包,
使用了什么秘钥来签名。本篇文章就为大家揭开这个面纱。
安卓源码编译的三个步骤:source build/envsetup.sh
;lunchxxxproject
;make
。签名两个步骤所做的事情,大家有兴趣可以自行研究。这里重点介绍make
这个过程做了什么。首先,
弄明白make
的目标是什么,APK
是怎么依赖到这个总目标的。这一块的逻辑我们主要关注build/make/core/main.mk
中的内容,这个mk
指定了系统层级的变量,比如通过soong
,ninja
来解析整个源码的编译文件。指定TOP
,TOPDIR
,BUILD_SYSTEM
等。
通过说明来看,放在第一个位置的就是我们make
默认的编译目标,droid_targets
默认又依赖于droidcore
。
而droidcore
默认就会依赖很多目标,如下图所示。
这么多目标,不一一说明,以systemimage
来说,该伪目标在build/make/core/Makefile
中指定了依赖的实体目标:systemimage:$(INSTALLED_SYSTEMIMAGE)
。最终通过层层依赖关系,在build-systemimage-target
函数通过build_image.py
将TARGET_OUT
目录下面system/
中的内容都打包到systemimg
。而一些APK
在编译过程中是会在system/
下面的app
或者priv-app
目录下面。这就形成了依赖关系,至于哪些APK
会编译到这个目录,算是后面遗留的课后作业吧。
其次, make
命令,引用了那些特别用于编译APK
的mk
。这个过程主要涉及到源码根目录下面的Makefile
和build/make/core
这个目录,相应mk
大家可以到build/make/core
下面查找,这里不列全路径。
在package_internal.mk
中会逐步去解析每个APK
下面的Android.mk
,比如LOCAL_PACKAGE_NAME,LOCAL_MODULE_TAGS
都是比较常见的APK
的属性,大家有想了解的可以细看。特别说明一下LOCAL_PACKAGE_OVERRIDES
,这个属性是去替换相应的APK
。比如在car
下面的Setting
就会去替换AOSP
原始的Setting
。对APK
的打包工具AAPT2
,以及res
,rro
在package_internal.mk
中都会去进行判断,以进行相关的打包动作。对打包感兴趣的可以仔细研究这一块,本篇文章我们主要关注APK
的签名。
在每个APK
中,我们可以通过LOCAL_CERTIFICATE
制定APK
签名类型:platform
,media,shared
或者test
。如果APK
没有指定这个变量的值,
则使用DEFAULT_SYSTEM_DEV_CERTIFICATE
的值,而DEFAULT_SYSTEM_DEV_CERTIFICATE
的值则是在project
层面进行配置的,如果未配置,则会在config.mk
中使用默认值,
这里特别强调一点,
修改DEFAULT_SYSTEM_DEV_CERTIFICATE
的值,
其实只是影响了一种APK
签名的key
,而不是所有的,
不能想当然,不然这里会出笑话。
如果都是系统默认的设置,
则不同APK
的LOCAL_CERTIFICATE
通过下面的逻辑,取得不同的值:Build/target/product/security/testkey;Build/target/product/security/media;Build/target/product/security/platform;Build/target/product/security/shared;
后面都是一些参数的传递,这里不赘述。
后面重要的逻辑就是调用了definitions.mk
里面的sign-package
函数进行APK
的签名操作。
这个特别说明一下JAVA
和SIGNAPK_JAR
的值:JAVA
的值为prebuilts/jdk/jdk9/linux-x86/bin/java
,
SIGNAPK_JAR为out/host/linux-x86/framework/signapk.jar,这个变量是需要我们实际关注的,apk具体签名的逻辑都是在这里面,要想进行客制化,重点在此。而该APK的源码在build/make/tools/signapk,关于这个用法大家可以自行研读源码,或者直接参考Google的说明文档https://developer.android.google.cn/studio/command-line/apksigner?hl=en。
关于APK 打包,重点在签名的逻辑,本篇文章就介绍到此,希望对大家有所帮助。留下两个进一步问题供大家自行研究: 什么变量决定了APK 最后打包到systemimg 还是vendor img ;APK 中的字节对齐是怎么做到的,有什么好处。 有具体问题都可以反馈出来,也欢迎大家进行投稿。