多渠道打包本质是改Android的productFlavors机制,通过编译期注入buildConfigField和manifestPlaceholders固化渠道标识到APK中,确保JS层和SDK能正确读取DCLOUD_STREAMAPP_CHANNEL。
多渠道打包本质是改什么?
uni-app 多渠道打包,不是靠 hbuilderx 点几下就能自动出几十个包的魔法,它底层就是靠 android 的 productflavors 机制,在编译时生成不同 buildconfigfield 和 manifestplaceholders,让每个渠道包能读到自己专属的渠道标识(比如 dcloud_streamapp_channel),再配合后端或 sdk 做渠道归因。
关键点在于:渠道信息必须在编译期固化进 APK,不能运行时靠 JS 动态写死。否则所有包都一样,渠道统计全乱。
- 渠道名最终要落到
BuildConfig.DCLOUD_STREAMAPP_CHANNEL字符串里,供 JS 层通过uni.getSystemInfoSync().buildVersion或自定义桥接读取 - 同时也要透传到
AndroidManifest.xml的meta-data或 intent-filter 中(如果某些 SDK 强制要求) - 包名(
applicationId)默认不随渠道变,除非你像部分老项目那样写成com.example.app_$channel$—— 这会导致无法共用同一应用更新通道,慎用
本地打包怎么配 flavor?别漏这三处
HBuilderX 的“本地打包”本质是把 uni-app 编译成一套 webview 资源,再塞进原生 Android 工程里。所以真正决定渠道逻辑的,是你本地 Android Studio 工程里的 build.gradle。
必须同步改三处:
- 在
android { ... }块内声明flavorDimensions "default" - 在
productFlavors { ... }下定义具体 flavor,例如:APP_CHANNEL_DOU { ... },每个 flavor 里都要设buildConfigField "String", "DCLOUD_STREAMAPP_CHANNEL", "\"com.qnt|...|1_APP_CHANNEL_DOU\"" - 在
defaultConfig { ... }或对应 flavor 内补上manifestPlaceholders = [DCLOUD_STREAMAPP_CHANNEL: "..."],否则AndroidManifest.xml里${DCLOUD_STREAMAPP_CHANNEL}会报错找不到变量
常见错误:只改了 buildConfigField,忘了 manifestPlaceholders,结果 JS 能读到渠道,但友盟/极光等 SDK 初始化失败,因为它们从 manifest 里取值。
渠道参数怎么传给 JS 层?别信 window.__GLOBAL__
uni-app 官方不提供开箱即用的渠道变量 API。你不能指望 uni.getSystemInfoSync() 直接返回渠道名 —— 它返回的是系统信息,不是构建配置。
正确做法是:在 App 启动时,由原生层把 BuildConfig.DCLOUD_STREAMAPP_CHANNEL 注入 JS 上下文。
- 方式一(推荐):用
uni.registerPlugin+ 自定义原生插件,在onCreate里调用uni.setStorageSync('channel', BuildConfig.DCLOUD_STREAMAPP_CHANNEL) - 方式二(轻量):在
main.js或app.vue的onLaunch里发一个plus.runtime.getProperty请求(仅限 5+ 环境),前提是你的离线 SDK 已在assets/data/dcloud_properties.json里预埋字段
容易踩的坑:有人试图在 manifest.json 里写 "$channel$" 占位符,指望 HBuilderX 替换 —— 这只在云打包中生效,且仅影响包名和名称,不生成 BuildConfig 字段,本地打包完全无效。
打完包怎么验证渠道对不对?别只看文件名
./gradlew assembleRelease 打出来的包名是 app-APP_CHANNEL_DOU-release.apk,但这只是 gradle task 名,不代表内容真的区分开了。
验证必须进包里查:
- 解压 APK,打开
classes.dex反编译(用 jadx-gui),搜DCLOUD_STREAMAPP_CHANNEL,确认字符串值是否匹配你定义的 flavor - 或更简单:用
unzip -p app-APP_CHANNEL_DOU-release.apk resources.arsc | strings | grep DCLOUD,看输出是否含对应渠道码 - 启动 App 后,用
adb logcat | grep "channel"捕获日志,确认初始化时打印的渠道值是否正确
最常被忽略的一点:签名配置。如果你在 buildTypes.release.signingConfig 里没指定 signingConfigs.release,或者 keystore 路径写错,打包会静默 fallback 到 debug 签名 —— 导致所有渠道包签名不一致,上架审核被拒,还查不出原因。










