如何为两个Flavor的Debug/Release版本配置不同签名?
Android多Flavor签名配置问题
背景
- Google登录出现异常,原因是应用的两个Flavor使用了相同的签名配置,导致Debug和Release版本的SHA1值一致。
- 异常仅出现在第二个Flavor的Release版本中,第一个Flavor的Build&Debug版本、第二个Flavor的Debug版本均正常工作。
问题
需要基于现有release-keystore生成新的签名配置,在Gradle文件中正确设置,要求保留原有的4个构建变体(freeDebug、freeRelease、paidDebug、paidRelease),但为paid相关的变体配置不同的签名。
假设两个包名分别为com.free和com.paid,当前简化后的Gradle配置如下:
defaultConfig { applicationId "com.free" ... } signingConfigs { debug { storeFile file('debug.keystore') storePassword "storePassword1" keyAlias "keyAlias1" keyPassword "keyPassword1" } release { storeFile file('release.keystore') storePassword "storePassword2" keyAlias "keyAlias2" keyPassword "keyPassword2" } } buildTypes { release { signingConfig signingConfigs.release ... } debug { ... } } flavorDimensions.add("default") productFlavors { free { dimension "default" applicationId "com.free" ... } paid { dimension "default" applicationId "com.paid" ... } } namespace 'com.free'
当前配置生成4个构建变体:
- freeDebug
- freeRelease
- paidDebug
- paidRelease
已尝试的方案
尝试拆分signingConfigs中的release配置,移除buildTypes中release的signingConfig设置,并将productFlavors拆分为4个,配置如下:
signingConfigs { //unchanged: debug { storeFile file('debug.keystore') storePassword "storePassword1" keyAlias "keyAlias1" keyPassword "keyPassword1" } //using new keystore file, split for 2 different flavors, and have new keyAlias and keyPassword for "paid" : releaseFree { storeFile file('new_release.keystore') storePassword "storePassword2" keyAlias "keyAlias2" keyPassword "keyPassword2" } releasePaid { storeFile file('new_release.keystore') storePassword "storePassword2" keyAlias "keyAlias3" keyPassword "keyPassword3" } } buildTypes { release { //commented this as it can't be used anymore (split and not shared) //signingConfig signingConfigs.release ... } debug { ... } } flavorDimensions.add("default") productFlavors { //split to 4 : free-debug, paid-debug, free-release, paid-release freeDebug { dimension "default" applicationId "com.free" //identical debug key configuration should work fine for both signingConfig signingConfigs.debug ... } paidDebug { dimension "default" applicationId "com.paid" //identical debug key configuration should work fine for both signingConfig signingConfigs.debug ... } freeRelease { dimension "default" applicationId "com.free" signingConfig signingConfigs.releaseFree ... } paidDebug { dimension "default" applicationId "com.paid" signingConfig signingConfigs.releasePaid ... } }
但生成了8个变体而非预期的4个,原因是每个Flavor都会和Debug/Release buildType组合,4个Flavor对应8个变体。
疑问
- 操作哪里错误?如何保留原来的4个构建变体?是否可以为每个Flavor指定buildType?或者需要设置两个dimension值?
- 当前signingConfigs的设置是否合理?同一keystore使用相同storePassword,不同Flavor使用不同keyAlias和keyPassword,这样是正确的吗?
解决方案
问题1:保留4个构建变体的正确配置
你错误地将buildType的职责合并到了productFlavors中,导致Flavor和buildType重复组合。正确的做法是保留原有的2个Flavor和2个buildType,通过遍历变体的方式为特定Flavor+buildType组合配置签名。
修改后的完整Gradle配置如下:
defaultConfig { applicationId "com.free" ... } signingConfigs { debug { storeFile file('debug.keystore') storePassword "storePassword1" keyAlias "keyAlias1" keyPassword "keyPassword1" } releaseFree { storeFile file('new_release.keystore') storePassword "storePassword2" keyAlias "keyAlias2" keyPassword "keyPassword2" } releasePaid { storeFile file('new_release.keystore') storePassword "storePassword2" keyAlias "keyAlias3" keyPassword "keyPassword3" } } buildTypes { release { // 移除全局的signingConfig设置 ... } debug { // Debug版本统一使用debug签名 signingConfig signingConfigs.debug ... } } flavorDimensions.add("default") productFlavors { free { dimension "default" applicationId "com.free" ... } paid { dimension "default" applicationId "com.paid" ... } } // 为特定变体配置签名 android.applicationVariants.all { variant -> if (variant.buildType.name == 'release') { if (variant.flavorName == 'free') { variant.signingConfig = signingConfigs.releaseFree } else if (variant.flavorName == 'paid') { variant.signingConfig = signingConfigs.releasePaid } } } namespace 'com.free'
此配置会保留原有的4个构建变体,且每个变体使用对应的签名配置。
问题2:签名配置的合理性
你的signingConfigs设置是合理且正确的:
- 同一个keystore可以包含多个密钥对(不同keyAlias),这是Android官方推荐的多Flavor签名方式之一。
- 每个Flavor使用独立的keyAlias,能生成不同的SHA1值,可解决Google登录的异常问题。
- 同一keystore使用相同的storePassword是正常的:storePassword用于解锁整个keystore文件,keyPassword用于解锁单个密钥对,二者可以相同或不同,只要保证每个keyAlias对应的keyPassword正确即可。
内容的提问来源于stack exchange,提问作者android developer
相关产品推荐
相关产品推荐

