android培训坑(5000个Android渠道包加班也打不完)

前言

最近,公司的一款App正在多渠道进行推广,渠道在推广过程中又使用了App马甲包(内部功能不变,App图标名称不一样)的方式增加关键词覆盖。

android培训坑(5000个Android渠道包加班也打不完)(1)

因为运营部门需要精确统计每个渠道以及每个马甲包的下载量以及用户注册量,所以每多增加一个渠道马甲包,开发都需要在productFlavors中手动添加一下配置。

当渠道马甲包还不是很多时手动打包还能接受,慢慢的马甲包越打越多到目前为止已经有5000多个马甲包,如果还是手动打包的话不仅会严重拖慢发版进度,重复的体力活更会让开发苦不堪言。

后来我们研究了一套全自动分布式多渠道马甲包打包方案,实现了只需半个小时就可以打完5000多个渠道马甲包,从此再也不用担心要加班啦!

android培训坑(5000个Android渠道包加班也打不完)(2)

目录
  1. 传统的多渠道打包方式为什么慢?
  2. 美团Walle多渠道打包工具为什么快?
  3. 全自动分布式多渠道马甲包打包方案分享
  4. 总结
传统的多渠道打包方式为什么慢?

想要分渠道统计数据,那么在App内部必然存在某个字段来标识不同的渠道,不同的渠道包在App内部的渠道标识肯定是不一样的,所以在每次打渠道包之前我们需要手动去更改这个渠道标识。

改个渠道标识能有多慢?

确实,改渠道标识很简单只要几秒钟,Android当中也可以通过productFlavors配置文件来提前配置好马甲包的相信息,再通过不同的打包命令来构建不同的渠道包。

但是耗时的是打APK包的过程,根据Android项目本身的大小不同以及电脑配置不同,一般每次打包耗时几分钟到十几分钟都属于正常情况。

能不能只打一个包再复制分别写入不同的渠道标识?

想法是好的,但是并不能实现,这是由于Android应用存在签名验证的机制。Android系统要求所有APK必须先使用证书进行数字签名,然后才能安装到设备上或进行更新。

android培训坑(5000个Android渠道包加班也打不完)(3)

如果APK文件发生了变动那么签名校验就无法通过,APK包也就无法进行安装或更新。

只打一个包再复制分别写入不同的渠道标识这个打包思路是对的,虽然打包之后不能将渠道标识直接写入到APK里,但其实我们只需要在APK中找到那么一小块区域,既能让我们写入渠道标识又不影响签名校验就行了。

美团Walle多渠道打包工具为什么快?

APK中还真有这么一小块区域,既能让我们写入渠道标识又不影响签名校验,美团开源的Android多渠道打包工具Walle就是按照这个思路实现的。

我们都知道APK文件本质上其实是一个ZIP压缩文件,将.apk后缀改成.zip后可以使用压缩工具直接打开。

Android 7.0(Nougat)之前的签名机制将整个APK文件分成三大块:

android培训坑(5000个Android渠道包加班也打不完)(4)

Android系统在7.0(Nougat)版本推出了一个新的应用签名方案APK Signature Scheme v2,新的签名方案会在Central Directory区块所在文件位置的前面添加一个APK Signing Block区块:

android培训坑(5000个Android渠道包加班也打不完)(5)

新签名方案生成的签名信息将会被保存在不受保护的区块2中, 而区块1、区块3、区块4都是受保护的区块,在签名后任何对区块1、区块3和区块4的修改都导致签名校验失败。

既然区块2不受保护,那么我们是不是可以将渠道信息写到这里呢?先来看看APK Signing Block的介绍:

android培训坑(5000个Android渠道包加班也打不完)(6)

APK Signing Block内部的数据结构为:2个8字节用来标示这个区块长度 + 16字节代表区块魔数(APK Sig Block 42) 一组不定长的ID-value键值对数据。新版签名方案生成的签名信息就是以ID(固定为0x7109871a)的ID-value的键值对格式保存在这个区块中的。

再来看一下新版签名方案的签名验证逻辑:

android培训坑(5000个Android渠道包加班也打不完)(7)

可以看出新版签名方案的验证逻辑为首先查找APK Signing Block区块,再去寻找ID等于APK_SIGNATURE_SCHEME_V2_BLOCK_ID(0x7109871a)的键值对获取签名值,对于其他的ID-value键值对并没有进行校验。

到这里我们基本就能明确美团的多渠道打包工具Walle的工作原理了:

  1. 首先打一个已经签过名APK母包,后面的渠道包都基于这个母包生成;
  2. 需要打渠道包时先复制一个母包,再将渠道标识按照ID-value键值对的格式写入到APK Signing Block区块中;
  3. APK在安装过程中进行的签名校验时并不会校验我们自定义的ID-value键值对,所以可以正常进行安装和更新;
  4. 在代码中我们可以通过某些方法读出APK Signing Block区块中我们自定义的ID-value键值对,从而获取到渠道标识;
全自动分布式多渠道马甲包打包方案分享

最后分享一个我们在用的全自动多渠道马甲包打包方案。

先来一张整个系统的架构图:

android培训坑(5000个Android渠道包加班也打不完)(8)

  1. 首先把所有需要打包的马甲包icon图标、app名称和渠道标识等信息统一提交到Redis缓存的队列中;
  2. 根据需要打包的数量和每次打包的耗时确定打包机器的数量,比如我需要打5000个马甲包,每个马甲包打包需要3分钟,如果100台机器一起打包,那每3分钟可以打100个包,打完5000个包需要150分钟,如果500台机器一起打包,那每3分钟可以打500个包,打完5000个包就只需要30分钟;
  3. 所有打包机器挂载同一块云盘用于集中保存所有的APK文件;

开这么多机器太麻烦?其实一点都不麻烦,现在云主机很方便,选择按使用时间付费,打完包直接释放就行了。

详细的打包流程图:

android培训坑(5000个Android渠道包加班也打不完)(9)

  1. 打包机器上开启一个定时任务不间断的从Redis领取打包任务;
  2. 替换源码中的icon图标和app名称;
  3. 执行gradlew命令打包,生成APK文件;
  4. 通过Walle CLI命令向APK中写入渠道标识;
  5. 将生成的渠道包保存到云盘;
总结

Android由于有签名验证机制的存在,传统的多渠道打包方案需要不断的替换渠道标识并重复进行打包操作。很明显,传统的多渠道打包方案效率很低,在渠道包数量较少的情况下可以采用这种方式手动打包。

美团开源的新一代Android多渠道打包工具Walle,通过向APK Signing Block区块中写入自定义渠道信息的方式实现了多渠道打包。

与传统的多渠道打包方案相比,使用Walle多渠道打包工具,无论打多少渠道包总是只需打包一次生成母包,再基于母包依次写入渠道信息即可,可以节约大量重复打包的时间。

“分享知识,收获快乐”

我是一名程序员,喜欢我的文章欢迎 关注 及 转发,我会经常与大家分享一些工作当中的编程技巧与经验。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。