Android开发中常常需要进行多渠道打包,并且在包名中加入特定的标识,例如在提测阶段的包名中加入版本号、版本名、打包的时间,便于区分不同的测试包。
配置发布渠道
为了能够生成不同渠道的安装包,一般需要进行构建变体的配置,一般使用产品风味来区分不同的渠道,产品风味也可以进行其它类型包的区分,如付费版与非付费版,因此在产品风味的基础上可以使用风味纬度来管理不同大类的风味,例如可以定义一个渠道纬度“channel”,负责管理渠道产品风味。一个付费纬度“pay”来管理付费产品风味,如下所示:android {
flavorDimnsions "channel", "pay"
productFlavors {
dev {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "dev"]
}
google {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "google"]
}
alibaba {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "alibaba"]
}
tencent {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "tencent"]
}
xiaomi {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "xiaomi"]
}
oppo {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "oppo"]
}
baidu {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: "baidu"]
}
// ...
paid {
dimension "pay"
}
free {
dimension "pay"
}
}
}
然而主流和次要渠道可能达到几十上百个,手动一一配置略显繁琐,借助基于Groovy的Gradle提供的强大编程能力,我们可以从一个文件中去加载所需的渠道。通过一个普通的文本文件或者json,csv文件就可以做到:
channel.csvdev
alibaba
tencent
xiaomi
oppo
baidu
然后可以通过从文件中读取渠道,然后添加到产品风味中:android {
flavorDimensions "channel"
def channelFile = rootProject.file("channel.csv")
def channels = channelFile.readLines()
productFlavors {
channels.each { channel ->
productFlavors.create(channel, {
dimension "channel"
manifestPlaceholders = [APP_CHANNEL: channel]
})
}
}
}
修改包名// If you use each() to iterate through the variant objects,
// you need to start using all(). That's because each() iterates
// through only the objects that already exist during configuration time—
// but those object don't exist at configuration time with the new model.
// However, all() adapts to the new model by picking up object as they are
// added during execution.
android.applicationVariants.all { variant ->
variant.outputs.all {
def name = outputFileName.replaceFirst("app-", "fafabtc-").replaceAll(".apk", "")
outputFileName = "${name}-${variant.versionName}.apk"
}
}