Android多渠道打包技术对比

前言

本文整理自我去年在公司内部做的一次分享,去掉了公司的信息,整理出来分享一下。
希望对读者有所帮助。

加入公司后,就一直负责App的多渠道打包,今天来分享一下多渠道打包技术的介绍与对比,以及我们最后的选择。

什么是多渠道打包技术

我们知道,由于某种黑暗力量,Android的亲爹市场 GooglePlay 不能进入大陆,导致大陆 Android 市场众多,如:小米、豌豆荚、华为等等等。

当新版本发布,我们需要通过渠道号来区分不同的市场,为不同市场生成不同的包,再把对应的包上传到各个市场。这种为App打出不同渠道包的技术称为多渠道打包技术。

怎么去做多渠道打包

多渠道打包实现有多种,但是有两点不会变:

  1. 渠道区分
  2. 打包

接下去介绍一下现今的多渠道打包技术,以及它们之间的对比。

Umeng+Gradle

我们 App 集成了 Umeng 的服务,所以就拿它举例了,事实上,不用 Umeng 也没有丝毫关系。

渠道的区分

在AndroidManifest.xml中配置一个meta-data:

1
2
3
<meta-data
android:name="UMENG_CHANNEL"
android:value="${CHANNEL_NAME}"/>

然后在app/build.gradle里配置productFlavors:

1
2
3
4
5
6
7
8
productFlavors {
def path = "channels.txt"
file(path).eachLine { channel ->
"$channel" {
manifestPlaceholders = [CHANNEL_NAME: channel]
}
}
}
PS:channels.txt 是渠道列表文件,每一行代表一个渠道,这样方便管理。

打包方法

使用 ./gradlew assembleRelease命令,就可以打出多渠道的包了。

原理

该种方式的打包原理是利用了 Gradle 的flavors功能来实现的,渠道的获取是通过如下代码方式获取。

1
2
ApplicationInfo appInfo = cxt.getPackageManager().getApplicationInfo(cxt.getPackageName(), PackageManager.GET_META_DATA);
String channel = String.valueOf(appInfo.metaData.get("UMENG_CHANNEL"));

优缺点

优点:

  1. 简单,易懂,没什么门槛,也不需要依赖其他工具与插件。
  2. Gradle强大的flavor功能,可以实现不同渠道拥有不同的代码实现,可以给渠道做定制包。
  3. 扩展性强大,没有兼容性问题。

缺点:

  1. 打包速度极慢,因为每个渠道包都是从“0到1”,渠道一多,打包时间以小时为单位。

PS:我们 App 几百个渠道,用这种方式打包需要2多个小时,怎么受得了?。

所以,该方式适合渠道不多的时候使用,或者不同渠道需要使用不同的代码。

美团的打包方案

上面说到,每个渠道包都是从“0到1”,然而实际上,渠道包之间的唯一差别仅仅在于一个渠道号(这里暂时只考虑不同渠道的代码相同),如果能拿已经打好的包,拿来修改一下渠道号,变成另一个渠道包,那这速度就能大幅度提高了。

美团的打包方案,利用META-INF(解压APK可以看到)不参与 APK 签名的原理,在META-INF新增空的文件来代表渠道,实现了这个功能,极大的提高了打包的速度。

渠道的区分

META-INF目录下新增空文件,再在代码中读取文件名获取()。

PS:可以去市场下载一个美团 APP 来解压一下看看。

打包方法

由于美团并没有给出具体的实现代码,所以我当时尝试的是开源实现:安卓多渠道打包工具

原理

上面已经提到了,META-INF不参与 APK 签名。

在META-INF目录下新增一个空的文件来代表渠道名。

这样就可以只打一次签名包,后续只需拷贝,新增渠道文件即可。

优缺点

优点:

  1. 速度极快,每打一个包就只需要复制一个APK,并新增一个空文件即可。(900个包一分钟,我天)
  2. 可以利用已存在的包打新的渠道包。(可多个)

第2点其实也是非常棒的优点,当需要一个新的渠道包时,不再需要停下工作,去保存代码,切分支,build,打包,只要一个已存在的包,一个命令就好,非常方便。

缺点:

  1. 不安全,由于不需要签名,所以任何人都可以拿到已有的包,修改成任意其他渠道的包,可能会被恶意利用污染渠道数据。
  2. 扩展性较差。(暂时没有Gradle的实现方案,相对来说选择余地较小,扩展性也差一些)
  3. 不支持 flavors
  4. 潜在风险,现在META-INF不参与APK签名,万一以后参与了,那么这套方案就失效了,当然这个概率估计很小。
  5. 似乎不支持 android 7.0?issue(没亲测,未知)
  6. 需要修改代码,修改渠道的获取方式(Umeng配置修改)

美团打包方式是一次大创新,最吸引人的就是速度快,真心快,就是打包的时间喝杯水再也不够了。

packer-ng-plugin

名字太长,简称为 packer 吧。号称『下一代Android打包工具』,拥有与美团的方案相媲美的打包速度。

原理

我们知道,其实 APK 是一个 Zip 文件,所以 APK 拥有 Zip 格式的特点。

该方法利用 Zip 格式的特点,修改Comment Length和File Comment两个字段,不会对ZIP文件造成破坏,将渠道信息放入其中,达到修改渠道的目的。由于修改以上内容也不需要重新签名打包,所以拥有与美团的方案相媲美的打包速度。

更多详情,见原项目Github。

渠道区分

渠道信息存放在APK文件的注释字段File Comment,在代码中使用 packer 提供的方法获取。

打包方法

提供了三种实现方式,Gradle、Java、Python,都可以使用。

优缺点

优点:

  1. 打包速度极快。(与美团方案速度差不多)
  2. 选择性更多,作者很良心,提供了Gradle,Java,Python三种实现。
  3. 扩展性强大,由于有 Gradle 的实现方案,所以扩展性有了保障。

缺点:

  1. 不支持 flavors。
  2. 需要修改代码,修改渠道的获取方式。(Umeng配置修改)
  3. 有潜在兼容性问题,具体可见 兼容性问题(已经解决)
  4. 潜在风险,Zip 格式万一修改,那么该方式失效,这概论应该也非常低。
  5. 已知360加固后,重新签名Apk后会抹去渠道信息。

小结

packer 利用 Zip 格式,又一个多渠道打包的创新,速度极快,又安全,非常棒!

对比

对比项 Gradle 美团 packer
是否支持 flavors 是 否 否
打包速度 慢 极快 极快
安全性 高 有风险 高
扩展性 高 较低 较高
兼容性问题 无 无 无
风险 无 极低 极低
加固影响 无 未测试 丢失渠道信息(360加固)

如何选择?

目前只有Gradle支持flavors功能,所以如果这个需求强烈,那么就只能选择Gradle。

如果没有这个需求,那么相对于美团打包的方式,第三种方式packer更加安全一些,速度方面也令人满意。

当然如果使用美团方式,可以在服务端过滤非法的渠道,也是可以的!~(看了美团的 APK,渠道是明文的,所以估计也是在服务端处理的,如果用的是 Umeng 统计,那么就不行喽)。

最后我们的选择是,以packer为主,Gradle为辅。

资料

美团Android自动化之旅—生成渠道包
安卓多渠道打包工具

程序亦非猿 wechat
都看到这里了,不关注下我的公众号吗?

热评文章