目录
简介
多渠道打包 是指在打包一个 Android 应用时,一次编译生成多个 APK 文件,每个 APK 文件针对一个特定的渠道。不同的渠道可能代表不同的应用商店、推广合作伙伴、地区等。每个渠道可能有不同的配置,例如不同的包名、资源、应用 ID、签名信息等。
打包配置
在打包之前,先聊一下我的需求。
我现在想打三个渠道的包,分别为 xiaomi
、huawei
、meizu
。通过多渠道打包的方式能够实现一次编译打三个包,且通过多渠道打包生成的包生成位置不同、包名不同的 App、AndroidManifest.xml
文件不同的包。
在 Android Studio 里,打包是由 Gradle
脚本去完成,因此,毫无疑问,以下的一些配置都是写在了 build.gradle
文件里。
由于 build.gradle 文件是从上往下执行的,因此,导入其它插件的代码一般写在最上面第一二行的位置。在 build.gradle 文件中,部分配置是有一个先后的执行顺序,就是说,他们的先后执行顺序如果错乱,就会出现各种奇怪的问题。
签名配置
多渠道打包 app 的签名配置在了 signingConfigs
里,分为了三个签名配置,分别是 xiaomiSigningConfigs
、huaweiSigningConfigs
、meizuSigningConfigs
。
groovy
android {
. . .
// 多渠道打包签名配置
signingConfigs {
// 配置 xiaomi 渠道的签名
xiaomiSigningConfigs {
storeFile file('../keystore/xiaomi.jks')
storePassword '123456'
keyAlias 'xiaomi'
keyPassword '123456'
}
// 配置 huawei 渠道的签名
huaweiSigningConfigs {
storeFile file('../keystore/huawei.jks')
storePassword '123456'
keyAlias 'huawei'
keyPassword '123456'
}
// 配置 meizu 渠道的签名
meizuSigningConfigs {
storeFile file('../keystore/meizu.jks')
storePassword '123456'
keyAlias 'meizu'
keyPassword '123456'
}
}
. . .
}
PS:填写
storeFile
的jks
文件配置时,需确认所在路径是否存在相应的jks
文件,否则会在Sync Now
或打包的时候出现某些奇奇怪怪的问题。
渠道配置
groovy
android {
. . .
// 配置渠道
productFlavors {
// xiaomi渠道
xiaomi {
// 配置与ndk相关的配置
ndk {
// 配置打包的安装包支持的设备架构
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
// 在包名后面添加包名的内容
applicationIdSuffix '.xiaomi'
// 替换strings.xml文件里对应名称的值
resValue "string", "app_name", "@string/app_name_xiaomi"
// 配置渠道打包所需的签名
signingConfig signingConfigs.xiaomiSigningConfigs
}
// huawei渠道
huawei {
applicationIdSuffix '.huawei'
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
resValue "string", "app_name", "@string/app_name_huawei"
signingConfig signingConfigs.huaweiSigningConfigs
}
// meizu渠道
meizu {
applicationIdSuffix '.meizu'
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
resValue "string", "app_name", "@string/app_name_meizu"
signingConfig signingConfigs.meizuSigningConfigs
}
}
. . .
}
PS:在渠道包配置里写了与签名相关的配置后,就不能够在
buildTypes
里写,否则会buildTypes
的签名被覆盖,且打包时只能使用命令行打包,使用开发工具打包签名会被选择打包签名的那一个签名给覆盖掉。
配置打包出来的App名称
groovy
android {
. . .
// 配置各个渠道包打包出来的app名称
def buildTime = buildTime()
android.applicationVariants.configureEach { variant ->
// 根据渠道名称判断打的渠道包是什么
if (variant.name.contains('xiaomi')) {
variant.outputs.configureEach { output ->
// 修改打出来的包的名称
output.outputFileName = "多渠道打包-xiaomi-${buildTime}.apk"
}
} else if (variant.name.contains('huawei')) {
variant.outputs.configureEach { output ->
output.outputFileName = "多渠道打包-huawei-${buildTime}.apk"
}
} else if (variant.name.contains('meizu')) {
variant.outputs.configureEach { output ->
output.outputFileName = "多渠道打包`-meizu-${buildTime}.apk"
}
}
}
. . .
}
正式包与测试包配置
groovy
android {
. . .
// 配置buildTypes
buildTypes {
// 配置打release包时的配置
release {
// 配置打release包时的签名(经过测试,无效果)
signingConfig signingConfigs.xiaomiSigningConfigs
debuggable false // 打出来的包是否包含调试信息
minifyEnabled false // 启用或禁用代码混淆
shrinkResources false // 是否移除未使用的资源
zipAlignEnabled true // 控制是否对apk进行优化
testCoverageEnabled false // 是否启用代码覆盖率报告
versionNameSuffix '-xiaomi' // 附加打包版本名称后缀
multiDexEnabled true // 是否启用多dex支持(适用于方法数超过65536的应用)
embedMicroApp false // 配置是否将微应用嵌入到主应用中
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// 配置打debug包时的配置
debug {
signingConfig signingConfigs.xiaomiSigningConfigs
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
. . .
}
打包方式
开发工具打包
打开 Android Studio,在顶部菜单栏依次选择 Build
👉 Generate Signed App Bundle / Apk
打包可以选择多个渠道打包,快捷键为 Control + 鼠标左键
,如下:
点击 Create
再过几分钟就会在 Module
下面生成对应的 app。
PS:使用 Android Studio 开发工具打包,多个app一起打包时,无法生成不同签名的app,最终打出来的app签名都会是同一个。
命令行打包
使用命令行打包前,需要提前配置好 Java 环境,并将其添加到系统的环境变量。
点击打开 Android Studio
的 Terminal
,输入 ./gradlew
确定是否可以正常使用。
bash
./gradlew
若已经完成多渠道的相关配置,继续执行 ./graldew tasks
查看可执行的命令,命令及执行结果如下:
bash
./graldew tasks
上图的执行结果展示了可执行的任务,打所有渠道的正式包使用的是 assembleRelease
命令:
bash
./graldew assembleRelease
执行完成如下图所示:
使用命令行打包不会提示打的包保存在了哪里,可以到该路径下查看 项目所在路径\csdn-demo\multi-channel-package\build\outputs\apk\
。
优缺点
优点
- 通过多渠道打包,可以统一管理应用的不同版本,简化发布流程和后续维护。
- 可以分别统计每个渠道的下载量、活跃用户、用户留存等数据,从而进行更精细的运营和推广。
- 可以针对不同市场定制不同版本的应用,满足不同国家和地区的法律法规、文化习惯和用户需求。
- 不同渠道可以使用不同的资源配置(如图标、启动页、应用名称等),满足不同市场或合作伙伴的需求。
- 不同的合作伙伴可能有不同的要求,通过多渠道打包可以更好地满足他们的需求,从而提升合作伙伴的满意度。
缺点
- 需要为不同渠道配置不同的资源和代码,增加了开发和维护的复杂度和工作量。
- 需要管理多个市场和渠道的发布和更新,这可能导致市场碎片化和管理难度增加。
- 不同渠道的资源配置可能会导致资源冗余,增大APK文件的体积,占用更多的存储空间。
- 多渠道打包需要配置多个构建变体,构建和发布流程变得更复杂,需要更细致的管理和协调。
- 不同渠道版本的应用可能存在差异,容易导致一些特定渠道版本出现质量问题,需要更多的测试和质量保证工作。
常见问题
- Caused by: groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.call() is applicable for argument types: (build_dnmb91jd12bvybe4o3deskrm1 r u n c l o s u r e 1 _run_closure1 runclosure1_closure4 c l o s u r e 10 ) v a l u e s : [ b u i l d d n m b 91 j d 12 b v y b e 4 o 3 d e s k r m 1 _closure10) values: [build_dnmb91jd12bvybe4o3deskrm1 closure10)values:[builddnmb91jd12bvybe4o3deskrm1_run_closure1 c l o s u r e 4 _closure4 closure4_closure10@5e0c18f1]
解决办法:buildTypes
对象里的参数不能以数字命名。 - Caused by: groovy.lang.MissingPropertyException: Could not get unknown property 'xiaomiSigningConfigs' for SigningConfig container of type org.gradle.api.internal.FactoryNamedDomainObjectContainer.
解决办法:
1、检查是否存在xiaomiSigningConfigs
的配置。
2、signingConfigs
的配置是否写在了buildTypes
的下方。(由于Gradle
编译顺序是从文件上往下编译的,如果buildTypes
在signingConfigs
的上方,意味着buildTypes
会先被编译,自然会出现这种找不到signingConfigs
里面配置的问题)
参考文档