android多渠道打包

 人参与 | 时间:2026-10-17 07:38:34

打一个包,多打包五分钟。渠道打十个包,多打包五十分钟。渠道打一百个包——如果你还在用Android Studio的多打包Build菜单一个个来,那这一天基本就交代进去了。渠道多渠道打包这事,多打包本质上不是渠道技术难题,是多打包效率问题。

国内做Android开发,渠道绕不开渠道包。多打包应用宝、渠道华为、多打包小米、渠道OPPO、多打包vivo、豌豆荚……每个渠道都要出一个APK,有些还要改渠道号、改应用名、甚至改图标。早年间我见过最离谱的做法:开发手动改一次AndroidManifest.xml里的渠道值,点一次Build,等两分钟,改下一个。一个版本发二十个渠道,一下午就没了,还容易改错。

Gradle productFlavors:最基础的多渠道方案

Android Gradle插件本身就提供了productFlavors,这是最正统的做法。在build.gradle里声明渠道,Gradle会为每个flavor生成独立的构建变体。

android {  flavorDimensions "channel" productFlavors {  yingyongbao {  dimension "channel" } huawei {  dimension "channel" } xiaomi {  dimension "channel" } } }

然后通过manifestPlaceholders把渠道值注入到AndroidManifest.xml里,代码运行时读出来就行。这套方案的好处是干净、可控,每个渠道可以有独立的资源、签名甚至依赖。缺点也明显:flavor多了之后,Gradle的配置阶段会变慢,构建变体数量是乘法增长的。三个维度各三个值,就是27个变体,IDE同步一次够你喝杯咖啡。

美团那套:在APK的META-INF里塞渠道信息

2016年前后,美团分享过一个方案,思路很巧。APK本身是个zip包,zip格式允许在META-INF目录下添加任意文件而不影响签名校验。于是他们在APK生成后,往META-INF里写入一个空文件,文件名就是渠道号,比如META-INF/channel_huawei。运行时读取这个文件名,渠道信息就拿到了。

这个方案的核心优势是快。生成一个渠道包只需要复制文件加改文件名,不用重新走一遍编译和签名流程。一个基础APK,脚本跑一遍,几百个渠道包几分钟搞定。但后来Android 11收紧了APK Signature Scheme v2的校验规则,往META-INF里塞东西会导致签名失效。这个方案在新版本上基本走不通了,除非你只用v1签名——但Google Play早就要求v2以上了。

现在的主流:加固平台自带的多渠道 + Walle

国内实际项目里,很多团队用的是加固厂商提供的多渠道打包服务。360加固、腾讯乐固、梆梆这些平台,上传一个母包,勾选渠道,平台帮你生成一堆渠道包。省事,但依赖第三方,渠道列表管理起来也麻烦。

如果自己控制构建流程,Walle是目前比较靠谱的开源方案。它的原理是在APK的签名块(Signing Block)里写入渠道信息,不影响v2签名校验。用法也简单,集成Walle的Gradle插件后,./gradlew assembleRelease出来的包自动带上渠道,再跑一个walle-cli就能批量生成所有渠道包。速度比productFlavors快一个数量级,而且支持v2签名。

我自己的项目从productFlavors迁到Walle之后,CI上的打包时间从十几分钟压到了一分半。渠道从十几个扩到六十多个,构建时间几乎没变。这个收益是实打实的。

几个容易踩的坑

渠道号读取的时机要注意。有些方案在Application.onCreate里读渠道,但这个时候如果渠道信息存在APK外部(比如Walle写在签名块里),读取本身需要IO操作,放在主线程会有轻微卡顿。建议放到子线程或者延迟初始化。

另外,渠道包和混淆配置的关系。如果你用productFlavors,每个flavor可以有自己的混淆规则,但Walle方案下所有渠道包共用同一个混淆配置。如果你的渠道差异只在渠道号本身,那没问题;如果不同渠道需要不同的代码逻辑,还是得回到flavor方案。

还有个细节:Google Play的渠道包和国内渠道包最好分开构建。Google Play要求AAB格式,国内渠道要APK,混在一起配容易出岔子。我一般是在CI上分两条流水线,一条出AAB传Google Play,一条出APK走国内渠道,互不干扰。

多渠道打包没有银弹。渠道少、差异大,用productFlavors;渠道多、差异小,用Walle或者加固平台。关键是想清楚自己的渠道数量和差异程度,别为了用新技术把简单问题搞复杂了。

顶: 897踩: 263