多渠道的需求点,在于同一个 App,需要有一些不同来区分它们,最常见的场景就是 Android 国内的市场,对不同的市场使用不同的渠道包,它们的代码是一致的,只是一个渠道号的数据不一样。这样区分的好处在于数据更清晰,我们知道那个渠道的用户是优质用户。

最朴素的方案

最容易想到的就是使用 Gradle 的 Flavor,使用 Flavor 的特性,生成不同的渠道标识。不过这种方式每生成一个渠道包都需要执行一遍构建过程,非常耗时。

另外一种方式就是使用 apktool 反编译 APK,修改其中的资源,添加渠道的标识,并进行重新打包签名,这种方式省去了构建过程,反编译,打包,签名这几个步骤也比较耗时。按照美团博客的数据,打包 900 个渠道包将近三个小时。

V1 签名下的多渠道打包方式

v1 下对签名的校验比较弱,美团给出了完整的解决方案,就是在以及打包签名好的 Apk 中,向 /META-INF 目录下,写入一个空文件,以文件名来标识渠道号。

多渠道打包 - 图1
使用这样的方案,并不会破坏 v1 签名,所以效率会很高。

而在腾讯的 VasDolly 中,其实是向 Apk 文件的 EOCD 部分,增加渠道的信息。

多渠道打包 - 图2

APK 文件本质上是一个 ZIP 包,而 EOCD 就是上图所示的第三部分,并且这部分是不被 v1 签名校验的,可以用来记录渠道信息。

V2 签名下的多渠道打包方式

v2 方案下,其实腾讯 VasDolly 和美团的 Walle 方案,并没有什么区别,因为验证更强,所以大家可操作的区域就只有那么多了。

多渠道打包 - 图3
使用 v2 签名后的 APK 文件结构中,插入了一个 APK Signing Block 的签名块。

在这个 APK 文件结构下,只有 块2 ,也就是记录 APK v2 签名信息的区域,不是全部参与 v2 签名的校验,所以大家都在这部分做文章。

APK Signing Block 中包含了多个「ID-值」的键值对,而 v2 签名的信息,会记录在 ID为 0x7109871a 中,而不会校验其他 ID 下的值。

因此,基于 v2 签名的多渠道方案就这样诞生了:在 APK 签名块中添加一个额外的 ID-值,用于记录渠道信息

美团 Walle 方案
腾讯 VasDolly 方案

总结

  • 中国 Android 环境碎片化严重,存在很多应用市场,需要针对不同应用市场生成不同渠道包

  • 使用 Gradle 多 flavor 实现多渠道打包构建时间过长,因此出现了其他多渠道打包的方案

  • 针对 v1 签名的应用,可以考虑在 v1 签名不验证的部分加入渠道信息,如 META-INFEOCD 部分

  • 针对 v2 签名的应用,由于 v2 签名不会验证 签名块 除 ID为 0x7109871a 的部分,因此可以在该区域增加其它键值对来标记渠道