Android编译系统分析系列文章已经是第六篇了,随着时间的流逝,随着工作中接触编译系统越来越多,对Android编译系统的理解也在一点点加深,这是令人欣慰的地方。最近遇到了系统apk签名的问题,于是专门分析了下签名部分的逻辑,将分析结果做个记录。
下面是其他五篇分析Android编译系统的文章,感兴趣的可以看下:
android编译系统分析(一)-source build/envsetup.sh与lunch
Android编译系统(二)-mm编译单个模块
android编译系统分析(三)-make
android编译系统(四)-实战:新增一个产品
Android编译系统分析(五)-system.img的生成过程
我们知道,当我们执行mm或者其他命令编译一个模块的时候,会在out\target\product\xxx\obj\APPS\xxxx生成三个apk,它们分别是:package.apk,package.apk.unaligned,package.apk.unsigned。其中package.apk应当是已经签过名的apk,package.apk.unsigned是没有签过名的apk,package.apk.unaligned是指没有使用zipalign工具优化过的apk,zipalign优化过的apk具有更高的效率。然而,按理讲package.apk是签过名的apk,可是,当我拿着这个apk来安装的时候,提示安装失败,重新使用自己的签名文件(系统也是使用该签名文件的,但不是build系统中默认的签名文件)进行签名后又可以安装,这是为什么呢?
package.apk确实是签过名的,可是当我们执行mm命令编译的时候,它是使用默认的系统签名文件签名的,如果一个公司使用它自己的签名文件给系统所有apk签名,就需要修改默认的系统签名文件的路径,改为自己的签名文件的路径,可是怎么改呢?
在我前面的博客: Android编译系统分析二:mm编译单个模块 一文中,我们分析了编译一个模块的具体过程,如果对编译一个模块不太清楚可参考下。当我们编译一个模块的时候,在package_internal.mk文件中,会有签名的相关逻辑:
# Pick a key to sign the package with. If this package hasn't specified
# an explicit certificate, use the default.
# Secure release builds will have their packages signed after the fact,
# so it's ok for these private keys to be in the clear.
ifeq ($(LOCAL_CERTIFICATE),)
LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
endif
ifeq ($(LOCAL_CERTIFICATE),EXTERNAL)
# The special value "EXTERNAL" means that we will sign it with the
# default devkey, apply predexopt, but then expect the final .apk
# (after dexopting) to be signed by an outside tool.
LOCAL_CERTIFICATE := $(